Browse Source

qcacld-3.0: Don't create vdev sync for pre CAC adapter again

Currently, for every pre CAC request a new vdev sync is getting created
and it will be destroyed only when SAP is stopped. So, there is a possible
memory leak if a valid pre CAC request is issued second time without SAP
stop.

To avoid this, don't create vdev sync for pre CAC request if pre CAC
adapter already exist.

Change-Id: If3f65648645b6801a1504a2d184dbc6928ff4771
CRs-Fixed: 2891360
Bapiraju Alla 4 years ago
parent
commit
68200a1b77

+ 1 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -515,6 +515,7 @@ typedef enum {
 	NET_DEV_HOLD_CACHE_STATION_STATS_CB = 57,
 	NET_DEV_HOLD_DISPLAY_TXRX_STATS = 58,
 	NET_DEV_HOLD_BUS_BW_MGR = 59,
+	NET_DEV_HOLD_START_PRE_CAC_TRANS = 60,
 
 	/* Keep it at the end */
 	NET_DEV_HOLD_ID_MAX

+ 1 - 0
core/hdd/src/wlan_hdd_main.c

@@ -5920,6 +5920,7 @@ static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid)
 		"NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP",
 		"NET_DEV_HOLD_CACHE_STATION_STATS_CB",
 		"NET_DEV_HOLD_DISPLAY_TXRX_STATS",
+		"NET_DEV_HOLD_START_PRE_CAC_TRANS",
 		"NET_DEV_HOLD_ID_MAX"};
 	int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings);
 

+ 41 - 4
core/hdd/src/wlan_hdd_sap_cond_chan_switch.c

@@ -417,14 +417,49 @@ release_intf_addr_and_return_failure:
 	return -EINVAL;
 }
 
+static int
+wlan_hdd_start_pre_cac_trans(struct hdd_context *hdd_ctx,
+			     struct osif_vdev_sync **out_vdev_sync,
+			     bool *is_vdev_sync_created)
+{
+	struct hdd_adapter *adapter, *next_adapter = NULL;
+	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_PRE_CAC_TRANS;
+	int errno;
+
+	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
+					   dbgid) {
+		if (!qdf_str_cmp(adapter->dev->name, SAP_PRE_CAC_IFNAME)) {
+			errno = osif_vdev_sync_trans_start(adapter->dev,
+							   out_vdev_sync);
+
+			hdd_adapter_dev_put_debug(adapter, dbgid);
+			if (next_adapter)
+				hdd_adapter_dev_put_debug(next_adapter,
+							  dbgid);
+			return errno;
+
+		}
+		hdd_adapter_dev_put_debug(adapter, dbgid);
+	}
+
+	errno = osif_vdev_sync_create_and_trans(hdd_ctx->parent_dev,
+						out_vdev_sync);
+	if (errno)
+		return errno;
+
+	*is_vdev_sync_created = true;
+	return 0;
+}
+
 int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint32_t chan_freq)
 {
 	struct hdd_adapter *adapter;
 	struct osif_vdev_sync *vdev_sync;
 	int errno;
+	bool is_vdev_sync_created = false;
 
-	errno = osif_vdev_sync_create_and_trans(hdd_ctx->parent_dev,
-						&vdev_sync);
+	errno = wlan_hdd_start_pre_cac_trans(hdd_ctx, &vdev_sync,
+					     &is_vdev_sync_created);
 	if (errno)
 		return errno;
 
@@ -432,14 +467,16 @@ int wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint32_t chan_freq)
 	if (errno)
 		goto destroy_sync;
 
-	osif_vdev_sync_register(adapter->dev, vdev_sync);
+	if (is_vdev_sync_created)
+		osif_vdev_sync_register(adapter->dev, vdev_sync);
 	osif_vdev_sync_trans_stop(vdev_sync);
 
 	return 0;
 
 destroy_sync:
 	osif_vdev_sync_trans_stop(vdev_sync);
-	osif_vdev_sync_destroy(vdev_sync);
+	if (is_vdev_sync_created)
+		osif_vdev_sync_destroy(vdev_sync);
 
 	return errno;
 }