From: Michal Kazior Date: Tue, 28 Oct 2014 09:23:09 +0000 (+0100) Subject: ath10k: avoid possible deadlock with scan timeout X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=4eb2e164872a086f42fb9fe5dfe93856ad740932;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git ath10k: avoid possible deadlock with scan timeout This should prevent deadlock predicted by the following splat: ====================================================== [ INFO: possible circular locking dependency detected ] 3.17.0-wl-ath+ #67 Not tainted ------------------------------------------------------- kworker/u32:1/7230 is trying to acquire lock: (&ar->conf_mutex){+.+.+.}, at: [] ath10k_scan_timeout_work+0x2d/0x50 [ath10k_core] but task is already holding lock: ((&(&ar->scan.timeout)->work)){+.+...}, at: [] process_one_work+0x151/0x470 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 ((&(&ar->scan.timeout)->work)){+.+...}: [] lock_acquire+0x85/0x100 [] flush_work+0x3d/0x270 [] __cancel_work_timer+0x7d/0x110 [] cancel_delayed_work_sync+0x13/0x20 [] ath10k_cancel_remain_on_channel+0x36/0x60 [ath10k_core] [] ieee80211_cancel_roc+0x1cc/0x2f0 [mac80211] [] ieee80211_mgmt_tx_cancel_wait+0x22/0x30 [mac80211] [] nl80211_tx_mgmt_cancel_wait+0xa8/0x130 [cfg80211] [] genl_family_rcv_msg+0x1a5/0x3c0 [] genl_rcv_msg+0x89/0xc0 [] netlink_rcv_skb+0xb1/0xc0 [] genl_rcv+0x2c/0x40 [] netlink_unicast+0x18d/0x200 [] netlink_sendmsg+0x31d/0x430 [] sock_sendmsg+0x9c/0xd0 [] ___sys_sendmsg+0x389/0x3a0 [] __sys_sendmsg+0x49/0x90 [] SyS_sendmsg+0x12/0x20 [] system_call_fastpath+0x1a/0x1f -> #0 (&ar->conf_mutex){+.+.+.}: [] __lock_acquire+0x1b6e/0x1ce0 [] lock_acquire+0x85/0x100 [] mutex_lock_nested+0x4b/0x370 [] ath10k_scan_timeout_work+0x2d/0x50 [ath10k_core] [] process_one_work+0x1b1/0x470 [] worker_thread+0x123/0x460 [] kthread+0xe4/0x100 [] ret_from_fork+0x7c/0xb0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock((&(&ar->scan.timeout)->work)); lock(&ar->conf_mutex); lock((&(&ar->scan.timeout)->work)); lock(&ar->conf_mutex); *** DEADLOCK *** Reported-by: Marek Puzyniak Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 4f150ef84ea3..a7e55efaeb2d 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3307,9 +3307,10 @@ static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw, struct ath10k *ar = hw->priv; mutex_lock(&ar->conf_mutex); - cancel_delayed_work_sync(&ar->scan.timeout); ath10k_scan_abort(ar); mutex_unlock(&ar->conf_mutex); + + cancel_delayed_work_sync(&ar->scan.timeout); } static void ath10k_set_key_h_def_keyidx(struct ath10k *ar, @@ -3826,10 +3827,11 @@ static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) struct ath10k *ar = hw->priv; mutex_lock(&ar->conf_mutex); - cancel_delayed_work_sync(&ar->scan.timeout); ath10k_scan_abort(ar); mutex_unlock(&ar->conf_mutex); + cancel_delayed_work_sync(&ar->scan.timeout); + return 0; }