diff options
author | Lior David <qca_liord@qca.qualcomm.com> | 2016-11-23 16:06:41 +0200 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2016-11-23 16:49:53 +0200 |
commit | dfb5b098e0f40b68aa07f2ec55f4dd762efefbfa (patch) | |
tree | d4ea87af0459920894f687a136a465f4eb65dbf4 /drivers/net/wireless/ath/wil6210/main.c | |
parent | 2c207eb8e6ab3f46d6c6a0daab16dc756562802b (diff) | |
download | lwn-dfb5b098e0f40b68aa07f2ec55f4dd762efefbfa.tar.gz lwn-dfb5b098e0f40b68aa07f2ec55f4dd762efefbfa.zip |
wil6210: fix deadlock when using fw_no_recovery option
When FW crashes with no_fw_recovery option, driver
waits for manual recovery with wil->mutex held, this
can easily create deadlocks.
Fix the problem by moving the wait outside the lock.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/main.c')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/main.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index b04ff87d6682..a9bbd0be2e3c 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -388,18 +388,19 @@ static void wil_fw_error_worker(struct work_struct *work) wil->last_fw_recovery = jiffies; + wil_info(wil, "fw error recovery requested (try %d)...\n", + wil->recovery_count); + if (!no_fw_recovery) + wil->recovery_state = fw_recovery_running; + if (wil_wait_for_recovery(wil) != 0) + return; + mutex_lock(&wil->mutex); switch (wdev->iftype) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_MONITOR: - wil_info(wil, "fw error recovery requested (try %d)...\n", - wil->recovery_count); - if (!no_fw_recovery) - wil->recovery_state = fw_recovery_running; - if (0 != wil_wait_for_recovery(wil)) - break; - + /* silent recovery, upper layers will see disconnect */ __wil_down(wil); __wil_up(wil); break; |