浏览代码

qcacld-3.0: Close small interface idle race window

There is an interface idle work that stops the driver module in cases of
adapter inactivity. This work grabs the iface_change_lock, which is also
grabbed before synchronously cancelling the interface idle work. This can
cause a deadlock situation where cancelling the work never finishes,
because the caller holds the lock the work needs in order to complete.
Hoist the calls to cancel the work out of locked regions to avoid the
potential deadlock situation.

Change-Id: Ie421e69e2026ad1de626daba1f72d002d9751013
CRs-Fixed: 2120671
Dustin Brown 7 年之前
父节点
当前提交
1fe30a8ff3
共有 2 个文件被更改,包括 5 次插入4 次删除
  1. 2 1
      core/hdd/src/wlan_hdd_driver_ops.c
  2. 3 3
      core/hdd/src/wlan_hdd_main.c

+ 2 - 1
core/hdd/src/wlan_hdd_driver_ops.c

@@ -1427,8 +1427,9 @@ static void wlan_hdd_purge_notifier(void)
 		return;
 	}
 
-	mutex_lock(&hdd_ctx->iface_change_lock);
 	qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
+
+	mutex_lock(&hdd_ctx->iface_change_lock);
 	cds_shutdown_notifier_call();
 	cds_shutdown_notifier_purge();
 	mutex_unlock(&hdd_ctx->iface_change_lock);

+ 3 - 3
core/hdd/src/wlan_hdd_main.c

@@ -2316,12 +2316,12 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx,
 		return -EINVAL;
 	}
 
-	mutex_lock(&hdd_ctx->iface_change_lock);
-	hdd_ctx->start_modules_in_progress = true;
-
 	hdd_set_idle_ps_config(hdd_ctx, false);
 	qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
 
+	mutex_lock(&hdd_ctx->iface_change_lock);
+	hdd_ctx->start_modules_in_progress = true;
+
 	switch (hdd_ctx->driver_status) {
 	case DRIVER_MODULES_UNINITIALIZED:
 		unint = true;