[PATCH v2 ath-current] wifi: ath12k: avoid flushing scan timeout under the wiphy lock
Runyu Xiao
runyu.xiao at seu.edu.cn
Thu Jul 2 23:02:19 PDT 2026
ath12k_mac_op_stop() is called with the wiphy lock held. It then takes
ah->hw_mutex and calls ath12k_mac_stop(), which synchronously cancels
ar->scan.timeout.
That can deadlock if the delayed work has started. The timeout worker
ath12k_scan_timeout_work() takes the same wiphy lock before aborting the
scan, so stop waits for a worker that cannot make progress until the
wiphy lock is released.
Drain ar->scan.timeout before entering the locked stop teardown, and
remove the synchronous cancel from ath12k_mac_stop(). This preserves the
stop-time drain while avoiding the wait-under-wiphy lock ordering.
Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
Cc: stable at vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao at seu.edu.cn>
---
Changes in v2:
- Rebase on ath.git ath-current.
- Use ath-current subject tag as requested.
- Move the synchronous scan timeout drain out of the locked stop path
instead of adding it in the wrong start-path context.
- Update Fixes to the ath12k commit that introduced the stop-time
scan.timeout drain.
drivers/net/wireless/ath/ath12k/mac.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index af354bef5c0d..6da9a2bda9fe 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -9931,7 +9931,6 @@ static void ath12k_mac_stop(struct ath12k *ar)
clear_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags);
- cancel_delayed_work_sync(&ar->scan.timeout);
wiphy_work_cancel(ath12k_ar_to_hw(ar)->wiphy, &ar->scan.vdev_clean_wk);
cancel_work_sync(&ar->regd_channel_update_work);
cancel_work_sync(&ar->regd_update_work);
@@ -9975,6 +9974,15 @@ void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend)
lockdep_assert_wiphy(hw->wiphy);
+ /*
+ * scan.timeout takes the wiphy lock before aborting the scan, so do
+ * not wait for it from the locked stop path below.
+ */
+ wiphy_unlock(hw->wiphy);
+ for_each_ar(ah, ar, i)
+ cancel_delayed_work_sync(&ar->scan.timeout);
+ wiphy_lock(hw->wiphy);
+
ath12k_drain_tx(ah);
mutex_lock(&ah->hw_mutex);
--
2.34.1
More information about the ath12k
mailing list