summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArunk Khandavalli <akhandav@codeaurora.org>2018-06-18 23:29:21 +0530
committernshrivas <nshrivas@codeaurora.org>2018-06-22 04:50:49 -0700
commit4aa4f0aa70b15924630112be82e8f248bef5453a (patch)
tree767d48bc1d9a8013a517b1c37de51df23aeebdfc
parentd3400d7e721522e91e97ae6bf17978cdf077156a (diff)
qcacld-3.0: Flush the restart sap work when the SAP is going down
Presently in the force switch to scc scenario to a channel which sta is connected a work is scheduled to restart SAP. Inbetween if the sap interface goes down the worker thread is not flushed. So, when the worker thread gets scheduled it can access the freed contexts of sap context. Hence Flush the restart sap context when the sap is going down. Change-Id: Ibb34392f33900aefb3085b06676818cbe9cbf066 CRs-Fixed: 2261585
-rw-r--r--core/cds/inc/cds_concurrency.h11
-rw-r--r--core/cds/src/cds_concurrency.c20
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c2
-rw-r--r--core/hdd/src/wlan_hdd_main.c12
4 files changed, 35 insertions, 10 deletions
diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h
index c70764bbd86d..a514ebead39d 100644
--- a/core/cds/inc/cds_concurrency.h
+++ b/core/cds/inc/cds_concurrency.h
@@ -1084,4 +1084,15 @@ bool cds_allow_sap_go_concurrency(enum cds_con_mode mode, uint8_t channel);
* Return: true or false
*/
bool cds_is_sta_sap_scc(uint8_t sap_ch);
+
+/**
+ * cds_flush_sta_ap_intf_work - Flush the restart sap work
+ * @hdd_ctx: HDD context pointer
+ *
+ * Flush the restart sap work and also free the memory
+ * if not already freed.
+ *
+ * Restart: None
+ */
+void cds_flush_sta_ap_intf_work(hdd_context_t *hdd_ctx);
#endif /* __CDS_CONCURRENCY_H */
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index caf037042acf..53da1abc8f28 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -7957,6 +7957,26 @@ static bool cds_is_sap_restart_required_after_sta_disconnect(
return true;
}
+void cds_flush_sta_ap_intf_work(hdd_context_t *hdd_ctx)
+{
+ ENTER();
+
+ if (hdd_ctx->sta_ap_intf_check_work_info)
+ cds_flush_work(&hdd_ctx->sta_ap_intf_check_work);
+ /*
+ * when sta_ap_intf_check_work is flushed above the work could already
+ * been running which will free the sta_ap_intf_check_work_info memory.
+ * So sanitize the sta_ap_intf_check_work_info and free the memory
+ * if not already freed.
+ */
+ if (hdd_ctx->sta_ap_intf_check_work_info) {
+ qdf_mem_free(hdd_ctx->sta_ap_intf_check_work_info);
+ hdd_ctx->sta_ap_intf_check_work_info = NULL;
+ }
+
+ EXIT();
+}
+
/**
* __cds_check_sta_ap_concurrent_ch_intf() - Restart SAP in
* STA-AP case
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 474c7fd7935c..df5fd934eb2e 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -8718,6 +8718,8 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
if (0 != ret)
return ret;
+ cds_flush_sta_ap_intf_work(pHddCtx);
+
/*
* If a STA connection is in progress in another adapter, disconnect
* the STA and complete the SAP operation. STA will reconnect
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index d63ccbda31c8..c97862630c82 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -5037,11 +5037,7 @@ QDF_STATUS hdd_stop_all_adapters(hdd_context_t *hdd_ctx, bool close_session)
ENTER();
cds_flush_work(&hdd_ctx->sap_pre_cac_work);
- if (hdd_ctx->sta_ap_intf_check_work_info) {
- cds_flush_work(&hdd_ctx->sta_ap_intf_check_work);
- qdf_mem_free(hdd_ctx->sta_ap_intf_check_work_info);
- hdd_ctx->sta_ap_intf_check_work_info = NULL;
- }
+ cds_flush_sta_ap_intf_work(hdd_ctx);
status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
@@ -5093,11 +5089,7 @@ QDF_STATUS hdd_reset_all_adapters(hdd_context_t *hdd_ctx)
ENTER();
cds_flush_work(&hdd_ctx->sap_pre_cac_work);
- if (hdd_ctx->sta_ap_intf_check_work_info) {
- cds_flush_work(&hdd_ctx->sta_ap_intf_check_work);
- qdf_mem_free(hdd_ctx->sta_ap_intf_check_work_info);
- hdd_ctx->sta_ap_intf_check_work_info = NULL;
- }
+ cds_flush_sta_ap_intf_work(hdd_ctx);
status = hdd_get_front_adapter(hdd_ctx, &adapterNode);