From c46f2d20cc8532bac3e55d33b997e431402165a3 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 3 Oct 2017 16:13:36 -0700 Subject: 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 | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 3a61a4a7c3d4..03ad98ce02b0 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -1290,8 +1290,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 639e1de5cdb1..8ff0ca7ba37d 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2047,11 +2047,11 @@ int hdd_wlan_start_modules(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, return -EINVAL; } + qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work); + mutex_lock(&hdd_ctx->iface_change_lock); hdd_ctx->start_modules_in_progress = true; - qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work); - switch (hdd_ctx->driver_status) { case DRIVER_MODULES_UNINITIALIZED: hdd_info("Wlan transition (UNINITIALIZED -> CLOSED)"); -- cgit v1.2.3