summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajeev Kumar <rajekuma@codeaurora.org>2017-03-16 19:44:39 -0700
committerSandeep Puligilla <spuligil@codeaurora.org>2017-03-21 21:35:08 -0700
commit0f3b1779504a12e27b90e0cddb517b44ca757b59 (patch)
treef910ccd44783133a9ce9e851873903ec5eb2bec7
parent76eaf56bb43b027527c50726f3ac23b05fe1c7df (diff)
qcacld-3.0: Fix race condition between external threads and module stop
External threads and interface change timer are racing against each other leading to various side effects. Fix the race condition between external threads and interface change timer by leveraging existing ssr/driver unload protection mechanism for module stop. Change-Id: Ic3d6d516161afee1dd65abb8f1eafe160bea54ff CRs-Fixed: 2021483
-rw-r--r--core/cds/inc/cds_sched.h7
-rw-r--r--core/cds/src/cds_sched.c5
-rw-r--r--core/hdd/src/wlan_hdd_main.c10
3 files changed, 22 insertions, 0 deletions
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index 49b9f9416830..a1ff67ceb27a 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -558,6 +558,13 @@ bool cds_wait_for_external_threads_completion(const char *caller_func);
int cds_get_gfp_flags(void);
/**
+ * cds_return_external_threads_count() - return active external thread calls
+ *
+ * Return: total number of active extrenal threads in driver
+ */
+int cds_return_external_threads_count(void);
+
+/**
* cds_shutdown_notifier_register() - Register for shutdown notification
* @cb : Call back to be called
* @priv : Private pointer to be passed back to call back
diff --git a/core/cds/src/cds_sched.c b/core/cds/src/cds_sched.c
index 215284b98532..2d1a0991237a 100644
--- a/core/cds/src/cds_sched.c
+++ b/core/cds/src/cds_sched.c
@@ -1651,6 +1651,11 @@ bool cds_wait_for_external_threads_completion(const char *caller_func)
return true;
}
+int cds_return_external_threads_count(void)
+{
+ return atomic_read(&ssr_protect_entry_count);
+}
+
/**
* cds_get_gfp_flags(): get GFP flags
*
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 75895f76c7f2..15c7cfbb243a 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -8427,6 +8427,16 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx)
mutex_lock(&hdd_ctx->iface_change_lock);
hdd_ctx->stop_modules_in_progress = true;
+ if (cds_return_external_threads_count() || hdd_ctx->isWiphySuspended) {
+ mutex_unlock(&hdd_ctx->iface_change_lock);
+ hdd_warn("External threads %d wiphy suspend %d",
+ cds_return_external_threads_count(),
+ hdd_ctx->isWiphySuspended);
+ qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
+ hdd_ctx->config->iface_change_wait_time);
+ return 0;
+ }
+
hdd_info("Present Driver Status: %d", hdd_ctx->driver_status);
switch (hdd_ctx->driver_status) {