Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a082c60 authored by Abdul Muqtadeer Ahmed's avatar Abdul Muqtadeer Ahmed Committed by snandini
Browse files

qcacld-3.0: Use hdd_for_each_adapter_dev_held_safe across the driver

hdd_for_each_adapter and hdd_for_each_adapter_dev_held are not
delete safe APIs. These APIs may cause synchronization issues.

To address all synchronization issues, use
hdd_for_each_adapter_dev_held_safe api across the driver.

Change-Id: Ic05a707d2f6ee4822a4c3f818c9706a1581bc89c
CRs-Fixed: 2795661
parent 566725fc
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -2796,7 +2796,7 @@ uint32_t cds_get_arp_stats_gw_ip(void *context)
void cds_incr_arp_stats_tx_tgt_delivered(void)
{
	struct hdd_context *hdd_ctx;
	struct hdd_adapter *adapter = NULL;
	struct hdd_adapter *adapter, *next_adapter = NULL;

	hdd_ctx = gp_cds_context->hdd_context;
	if (!hdd_ctx) {
@@ -2804,10 +2804,15 @@ void cds_incr_arp_stats_tx_tgt_delivered(void)
		return;
	}

	hdd_for_each_adapter(hdd_ctx, adapter) {
		if (QDF_STA_MODE == adapter->device_mode)
	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
		if (adapter->device_mode == QDF_STA_MODE) {
			dev_put(adapter->dev);
			if (next_adapter)
				dev_put(next_adapter->dev);
			break;
		}
		dev_put(adapter->dev);
	}

	if (adapter)
		adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent++;
@@ -2821,7 +2826,7 @@ void cds_incr_arp_stats_tx_tgt_delivered(void)
void cds_incr_arp_stats_tx_tgt_acked(void)
{
	struct hdd_context *hdd_ctx;
	struct hdd_adapter *adapter = NULL;
	struct hdd_adapter *adapter, *next_adapter = NULL;

	hdd_ctx = gp_cds_context->hdd_context;
	if (!hdd_ctx) {
@@ -2829,10 +2834,15 @@ void cds_incr_arp_stats_tx_tgt_acked(void)
		return;
	}

	hdd_for_each_adapter(hdd_ctx, adapter) {
		if (QDF_STA_MODE == adapter->device_mode)
	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
		if (adapter->device_mode == QDF_STA_MODE) {
			dev_put(adapter->dev);
			if (next_adapter)
				dev_put(next_adapter->dev);
			break;
		}
		dev_put(adapter->dev);
	}

	if (adapter)
		adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt++;
+0 −36
Original line number Diff line number Diff line
@@ -2301,16 +2301,6 @@ typedef QDF_STATUS (*hdd_adapter_iterate_cb)(struct hdd_adapter *adapter,
QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb,
			       void *context);

/**
 * hdd_for_each_adapter - adapter iterator macro
 * @hdd_ctx: the global HDD context
 * @adapter: an hdd_adapter pointer to use as a cursor
 */
#define hdd_for_each_adapter(hdd_ctx, adapter) \
	for (hdd_get_front_adapter(hdd_ctx, &adapter); \
	     adapter; \
	     hdd_get_next_adapter(hdd_ctx, adapter, &adapter))

/**
 * __hdd_take_ref_and_fetch_front_adapter - Helper macro to lock, fetch front
 * adapter, take ref and unlock.
@@ -2372,32 +2362,6 @@ QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb,
 */
#define __hdd_is_adapter_valid(_adapter) !!_adapter

/**
 * hdd_for_each_adapter_dev_held - Adapter iterator with dev_hold called
 * @hdd_ctx: the global HDD context
 * @adapter: an hdd_adapter pointer to use as a cursor
 *
 * This iterator will take the reference of the netdev associated with the
 * given adapter so as to prevent it from being removed in other context.
 * If the control goes inside the loop body then the dev_hold has been invoked.
 *
 *                           ***** NOTE *****
 * Before the end of each iteration, dev_put(adapter->dev) must be
 * called. Not calling this will keep hold of a reference, thus preventing
 * unregister of the netdevice.
 *
 * Usage example:
 *                 hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
 *                         <work involving adapter>
 *                         <some more work>
 *                         dev_put(adapter->dev)
 *                 }
 */
#define hdd_for_each_adapter_dev_held(hdd_ctx, adapter) \
	for (__hdd_take_ref_and_fetch_front_adapter(hdd_ctx, adapter); \
	     __hdd_is_adapter_valid(adapter); \
	     __hdd_take_ref_and_fetch_next_adapter(hdd_ctx, adapter))

/**
 * hdd_for_each_adapter_dev_held_safe - Adapter iterator with dev_hold called
 *                                      in a delete safe manner
+9 −2
Original line number Diff line number Diff line
@@ -399,7 +399,7 @@ hdd_conn_get_connected_cipher_algo(struct hdd_station_ctx *sta_ctx,
struct hdd_adapter *hdd_get_sta_connection_in_progress(
			struct hdd_context *hdd_ctx)
{
	struct hdd_adapter *adapter = NULL;
	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
	struct hdd_station_ctx *hdd_sta_ctx;

	if (!hdd_ctx) {
@@ -407,7 +407,7 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress(
		return NULL;
	}

	hdd_for_each_adapter(hdd_ctx, adapter) {
	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
		hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
		if ((QDF_STA_MODE == adapter->device_mode) ||
		    (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
@@ -416,6 +416,9 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress(
			    hdd_sta_ctx->conn_info.conn_state) {
				hdd_debug("vdev_id %d: Connection is in progress",
					  adapter->vdev_id);
				dev_put(adapter->dev);
				if (next_adapter)
					dev_put(next_adapter->dev);
				return adapter;
			} else if ((eConnectionState_Associated ==
				   hdd_sta_ctx->conn_info.conn_state) &&
@@ -424,9 +427,13 @@ struct hdd_adapter *hdd_get_sta_connection_in_progress(
							adapter->vdev_id)) {
				hdd_debug("vdev_id %d: Key exchange is in progress",
					  adapter->vdev_id);
				dev_put(adapter->dev);
				if (next_adapter)
					dev_put(next_adapter->dev);
				return adapter;
			}
		}
		dev_put(adapter->dev);
	}
	return NULL;
}
+16 −5
Original line number Diff line number Diff line
@@ -5596,11 +5596,11 @@ wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
				enum QDF_OPMODE device_mode)
{
	struct hdd_adapter *adapter;
	struct hdd_adapter *adapter, *next_adapter = NULL;
	struct hdd_ap_ctx *ap_ctx;
	struct hdd_station_ctx *sta_ctx;
	hdd_for_each_adapter(hdd_ctx, adapter) {
	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
		if ((device_mode == adapter->device_mode) &&
		    (device_mode == QDF_SAP_MODE)) {
			ap_ctx =
@@ -5617,6 +5617,9 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
				hdd_ctx->pdev,
				ap_ctx->operating_chan_freq)) {
				hdd_err("SAP running on DFS channel");
				dev_put(adapter->dev);
				if (next_adapter)
					dev_put(next_adapter->dev);
				return true;
			}
		}
@@ -5635,9 +5638,13 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
				hdd_ctx->pdev,
				sta_ctx->conn_info.chan_freq))) {
				hdd_err("client connected on DFS channel");
				dev_put(adapter->dev);
				if (next_adapter)
					dev_put(next_adapter->dev);
				return true;
			}
		}
		dev_put(adapter->dev);
	}
	return false;
@@ -11107,13 +11114,15 @@ static enum sta_roam_policy_dfs_mode wlan_hdd_get_sta_roam_dfs_mode(
 */
uint8_t hdd_get_sap_operating_band(struct hdd_context *hdd_ctx)
{
	struct hdd_adapter *adapter;
	struct hdd_adapter *adapter, *next_adapter = NULL;
	uint32_t  operating_chan_freq;
	uint8_t sap_operating_band = 0;
	hdd_for_each_adapter(hdd_ctx, adapter) {
		if (adapter->device_mode != QDF_SAP_MODE)
	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
		if (adapter->device_mode != QDF_SAP_MODE) {
			dev_put(adapter->dev);
			continue;
		}
		operating_chan_freq = adapter->session.ap.operating_chan_freq;
		if (WLAN_REG_IS_24GHZ_CH_FREQ(operating_chan_freq))
@@ -11123,6 +11132,8 @@ uint8_t hdd_get_sap_operating_band(struct hdd_context *hdd_ctx)
			sap_operating_band = BAND_5G;
		else
			sap_operating_band = BAND_ALL;
		dev_put(adapter->dev);
	}
	return sap_operating_band;
+2 −2
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ static int wlan_hdd_recovery_notifier_call(struct notifier_block *block,
	struct hdd_context *hdd_ctx;
	struct qdf_notifer_data *hdd_hang_data = data;
	uint8_t *hdd_buf_ptr;
	struct hdd_adapter *adapter;
	struct hdd_adapter *adapter, *next_adapter = NULL;
	uint32_t total_len;
	struct wlan_objmgr_vdev *vdev;
	struct hdd_hang_event_fixed_param *cmd;
@@ -76,7 +76,7 @@ static int wlan_hdd_recovery_notifier_call(struct notifier_block *block,
		hdd_hang_data->offset += total_len;
	}

	hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter) {
		vdev = hdd_objmgr_get_vdev(adapter);
		if (!vdev) {
			dev_put(adapter->dev);
Loading