Ver Fonte

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>
Lior David há 8 anos atrás
pai
commit
dfb5b098e0
1 ficheiros alterados com 8 adições e 7 exclusões
  1. 8 7
      drivers/net/wireless/ath/wil6210/main.c

+ 8 - 7
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->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);
 	mutex_lock(&wil->mutex);
 	switch (wdev->iftype) {
 	switch (wdev->iftype) {
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_P2P_CLIENT:
 	case NL80211_IFTYPE_P2P_CLIENT:
 	case NL80211_IFTYPE_MONITOR:
 	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_down(wil);
 		__wil_up(wil);
 		__wil_up(wil);
 		break;
 		break;