From 36049720ff14130e5fd074904c998b6b1490772a Mon Sep 17 00:00:00 2001 From: Will Huang Date: Fri, 13 Apr 2018 11:48:51 +0800 Subject: [PATCH] qcacld-3.0: Move qdf_cancel_delayed_work to __hdd_module_exit If hdd_wlan_stop_modules is called by hdd_iface_change_callback which is invoke by a delayed worker, and a race condition happen that rmmod call in during hdd_wlan_stop_modules, although cnss driver will serialize wlan remove with the wlan shutdown invoked by delayed worker, CNSS_DRIVER_UNLOADING still got set and wlan shutdown will invoke remove wlan, which will try to sync cancel delayed worker and wait for each other to deadlock. If move qdf_cancel_delayed_work() from hdd_wlan_exit() to __hdd_module_exit(), it will flush/wait in a different context of cnss driver worker, so avoid deadlock hit. Change-Id: I6bc58e8ae70291d5490560310e90abc52421b59f CRs-Fixed: 2222381 --- core/hdd/src/wlan_hdd_main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index af5de32a9d2d..b2975740f3b3 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -6504,8 +6504,6 @@ static void hdd_wlan_exit(struct hdd_context *hdd_ctx) hdd_enter(); - qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work); - hdd_unregister_notifiers(hdd_ctx); hdd_bus_bandwidth_destroy(hdd_ctx); @@ -11901,12 +11899,20 @@ err_hdd_init: */ static void __hdd_module_exit(void) { + struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR); + if (!hdd_ctx) { + hdd_err("hdd context is NULL return!!"); + return; + } + hdd_wait_for_recovery_completion(); + qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work); + wlan_hdd_unregister_driver(); qdf_wake_lock_destroy(&wlan_wake_lock);