ソースを参照

qcacld-3.0: Set unloading before grabbing lock

In wlan_hdd_pld_remove(), a global mutext is grabbed before setting the
global "unloading" flag. In the case of __hdd_open(), this flag is
checked before also grabbing the same lock. Ultimately this can lead to
deadlocks when other shared locks are involved. As a short-to-medium
term work around, set the unloading flag before waiting for external
threads to exit. After external threads have exited, then grab the lock
to avoid deadlocking with external threads like those invoking
__hdd_open(). Effectively, this does a stop-and-flush on external
threads into the driver before unloading.

Change-Id: Iaaf52d730807abd9a99950970988ec58a1abb87d
CRs-Fixed: 2251271
Dustin Brown 6 年 前
コミット
b1c8990ec8
1 ファイル変更4 行追加4 行削除
  1. 4 4
      core/hdd/src/wlan_hdd_driver_ops.c

+ 4 - 4
core/hdd/src/wlan_hdd_driver_ops.c

@@ -471,12 +471,16 @@ static void wlan_hdd_remove(struct device *dev)
 	if (!cds_wait_for_external_threads_completion(__func__))
 		hdd_warn("External threads are still active attempting driver unload anyway");
 
+	mutex_lock(&hdd_init_deinit_lock);
+	hdd_start_driver_ops_timer(eHDD_DRV_OP_REMOVE);
 	if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
 		epping_disable();
 		epping_close();
 	} else {
 		__hdd_wlan_exit();
 	}
+	hdd_stop_driver_ops_timer();
+	mutex_unlock(&hdd_init_deinit_lock);
 
 	cds_set_driver_in_bad_state(false);
 	cds_set_unload_in_progress(false);
@@ -1267,13 +1271,9 @@ static void wlan_hdd_pld_remove(struct device *dev,
 		     enum pld_bus_type bus_type)
 {
 	hdd_enter();
-	mutex_lock(&hdd_init_deinit_lock);
-	hdd_start_driver_ops_timer(eHDD_DRV_OP_REMOVE);
 
 	wlan_hdd_remove(dev);
 
-	hdd_stop_driver_ops_timer();
-	mutex_unlock(&hdd_init_deinit_lock);
 	hdd_exit();
 }