diff mbox series

[v2,for,v5.12,4/7] iwlwifi: fw: fix notification wait locking

Message ID iwlwifi.20210326125611.c3b2e3d6b58b.Ic56f351d04674df70567bab0269cba91bdbc853c@changeid (mailing list archive)
State Accepted
Commit 9c04fd95fa830d60e5bdb08bcd7ff68d7e120e5b
Delegated to: Kalle Valo
Headers show
Series iwlwifi: fixes intended for v5.12 2021-03-26 v2 | expand

Commit Message

Luca Coelho March 26, 2021, 10:57 a.m. UTC
From: Johannes Berg <johannes.berg@intel.com>

Since we now call iwl_notification_wait_notify() from the
NAPI poll in soft-IRQ, we get a (valid) lockdep complaint
that we could get a deadlock by taking the spinlock from
sleeping context and then getting the soft-IRQ that also
tries to take it (in NAPI polling).

Fix this by disabling soft-IRQs for this lock.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Fixes: 25edc8f259c7 ("iwlwifi: pcie: properly implement NAPI")
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c
index 3dbc6f3f92cc..231d2517f398 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c
@@ -1,6 +1,6 @@ 
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2005-2014 Intel Corporation
+ * Copyright (C) 2005-2014, 2021 Intel Corporation
  * Copyright (C) 2015-2017 Intel Deutschland GmbH
  */
 #include <linux/sched.h>
@@ -26,7 +26,7 @@  bool iwl_notification_wait(struct iwl_notif_wait_data *notif_wait,
 	if (!list_empty(&notif_wait->notif_waits)) {
 		struct iwl_notification_wait *w;
 
-		spin_lock(&notif_wait->notif_wait_lock);
+		spin_lock_bh(&notif_wait->notif_wait_lock);
 		list_for_each_entry(w, &notif_wait->notif_waits, list) {
 			int i;
 			bool found = false;
@@ -59,7 +59,7 @@  bool iwl_notification_wait(struct iwl_notif_wait_data *notif_wait,
 				triggered = true;
 			}
 		}
-		spin_unlock(&notif_wait->notif_wait_lock);
+		spin_unlock_bh(&notif_wait->notif_wait_lock);
 	}
 
 	return triggered;
@@ -70,10 +70,10 @@  void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
 {
 	struct iwl_notification_wait *wait_entry;
 
-	spin_lock(&notif_wait->notif_wait_lock);
+	spin_lock_bh(&notif_wait->notif_wait_lock);
 	list_for_each_entry(wait_entry, &notif_wait->notif_waits, list)
 		wait_entry->aborted = true;
-	spin_unlock(&notif_wait->notif_wait_lock);
+	spin_unlock_bh(&notif_wait->notif_wait_lock);
 
 	wake_up_all(&notif_wait->notif_waitq);
 }