From 1fe30a8ff3ec5e63050d522278c35387f2bf6ce8 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 3 Oct 2017 16:13:36 -0700 Subject: [PATCH] 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 --- core/hdd/src/wlan_hdd_driver_ops.c | 3 ++- core/hdd/src/wlan_hdd_main.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index e28c329374ed..8334162e0107 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/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); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 6eca640a1426..31e9e7512b64 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/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;