From 8baf7c8ab00ef57659202c2777a04af1e9893aba Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Tue, 11 Oct 2016 01:26:59 -0400 Subject: [PATCH] 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) --- core/hdd/inc/wlan_hdd_main.h | 3 +-- core/hdd/src/wlan_hdd_cfg80211.c | 22 +++++++++++++++++++++- core/hdd/src/wlan_hdd_hostapd.c | 18 ++---------------- core/hdd/src/wlan_hdd_main.c | 1 + 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 398e7c2f592e..bfd9115d7817 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/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) */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 2e9494a6182b..b8ed55b67718 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/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 diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index c3dd96c240fe..e9738a16664e 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/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); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 3897c1252c62..1cc03ca266d5 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/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);