Kaynağa Gözat

qcacld-3.0: Fix acs_cfg.ch_list memory leak

qcacld-2.0 to qcacld-3.0 propagation

If ACS failed, the __wlan_hdd_cfg80211_stop_ap
will not be called to free the ch_list.
Add new API wlan_hdd_undo_acs to do cleanup of
DO_ACS to free ch_list memory. And call the API
in hdd_deinit_adapter to fix ch_list leak issue.

CRs-Fixed: 1002207
Change-Id: If3285739f2387928a1d7578f9d14089a486a6d9e
(cherry picked from commit e55d0c20e574a63b5002650529054ace24ad7cad)
Liangwei Dong 8 yıl önce
ebeveyn
işleme
8baf7c8ab0

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

@@ -1941,11 +1941,10 @@ static inline void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
 }
 #endif
 void hdd_wlan_update_target_info(hdd_context_t *hdd_ctx, void *context);
-
 enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode);
-
 void hdd_ch_avoid_cb(void *hdd_context, void *indi_param);
 void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctx);
 int hdd_enable_disable_ca_event(hdd_context_t *hddctx,
 				uint8_t set_value);
+void wlan_hdd_undo_acs(hdd_adapter_t *adapter);
 #endif /* end #if !defined(WLAN_HDD_MAIN_H) */

+ 21 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1621,7 +1621,7 @@ out:
 		if (temp_skbuff != NULL)
 			return cfg80211_vendor_cmd_reply(temp_skbuff);
 	}
-
+	wlan_hdd_undo_acs(adapter);
 	clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
 
 	return status;
@@ -1653,6 +1653,26 @@ static int wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 	return ret;
 }
 
+/**
+ * wlan_hdd_undo_acs : Do cleanup of DO_ACS
+ * @adapter:  Pointer to adapter struct
+ *
+ * This function handle cleanup of what was done in DO_ACS, including free
+ * memory.
+ *
+ * Return: void
+ */
+
+void wlan_hdd_undo_acs(hdd_adapter_t *adapter)
+{
+	if (adapter == NULL)
+		return;
+	if (adapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list) {
+		qdf_mem_free(adapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
+		adapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list = NULL;
+	}
+}
+
 /**
  * wlan_hdd_cfg80211_start_pending_acs : Start pending ACS procedure for SAP
  * @work:  Linux workqueue struct pointer for ACS work

+ 2 - 16
core/hdd/src/wlan_hdd_hostapd.c

@@ -7603,21 +7603,8 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 
 	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
 	ret = wlan_hdd_validate_context(pHddCtx);
-	if (0 != ret) {
-		if (cds_is_driver_unloading()) {
-			/*
-			 * Unloading the driver so free the memory for ch_list,
-			 * otherwise it will result in memory leak
-			 */
-			if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list) {
-				qdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.
-					acs_cfg.ch_list);
-				pAdapter->sessionCtx.ap.sapConfig.acs_cfg.
-					ch_list = NULL;
-			}
-		}
+	if (0 != ret)
 		return ret;
-	}
 
 	status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
 	while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
@@ -7663,8 +7650,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 		qdf_spin_unlock(&pHddCtx->sap_update_info_lock);
 	}
 	pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
-	if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list)
-		qdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
+	wlan_hdd_undo_acs(pAdapter);
 	qdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
 						sizeof(struct sap_acs_cfg));
 	hdd_hostapd_stop(dev);

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

@@ -2916,6 +2916,7 @@ static void hdd_ap_adapter_deinit(hdd_context_t *hdd_ctx,
 		hdd_wmm_adapter_close(adapter);
 		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
 	}
+	wlan_hdd_undo_acs(adapter);
 
 	hdd_cleanup_actionframe(hdd_ctx, adapter);