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
此提交包含在:
Rajeev Kumar
2017-03-16 19:44:39 -07:00
提交者 Sandeep Puligilla
父節點 541d2b8fb6
當前提交 86177c2c77
共有 3 個檔案被更改,包括 22 行新增0 行删除

查看文件

@@ -467,6 +467,13 @@ void cds_ssr_unprotect(const char *caller_func);
bool cds_wait_for_external_threads_completion(const char *caller_func); bool cds_wait_for_external_threads_completion(const char *caller_func);
int cds_get_gfp_flags(void); 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 * cds_shutdown_notifier_register() - Register for shutdown notification
* @cb : Call back to be called * @cb : Call back to be called

查看文件

@@ -1179,6 +1179,11 @@ bool cds_wait_for_external_threads_completion(const char *caller_func)
return true; return true;
} }
int cds_return_external_threads_count(void)
{
return atomic_read(&ssr_protect_entry_count);
}
/** /**
* cds_get_gfp_flags(): get GFP flags * cds_get_gfp_flags(): get GFP flags
* *

查看文件

@@ -8735,6 +8735,16 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx)
mutex_lock(&hdd_ctx->iface_change_lock); mutex_lock(&hdd_ctx->iface_change_lock);
hdd_ctx->stop_modules_in_progress = true; 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); hdd_info("Present Driver Status: %d", hdd_ctx->driver_status);
switch (hdd_ctx->driver_status) { switch (hdd_ctx->driver_status) {