Ver código fonte

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
Will Huang 7 anos atrás
pai
commit
36049720ff
1 arquivos alterados com 8 adições e 2 exclusões
  1. 8 2
      core/hdd/src/wlan_hdd_main.c

+ 8 - 2
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);