Commit 9c04fd95 authored by Johannes Berg's avatar Johannes Berg Committed by Kalle Valo
Browse files

iwlwifi: fw: fix notification wait locking



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: default avatarJohannes Berg <johannes.berg@intel.com>
Fixes: 25edc8f2 ("iwlwifi: pcie: properly implement NAPI")
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/iwlwifi.20210326125611.c3b2e3d6b58b.Ic56f351d04674df70567bab0269cba91bdbc853c@changeid
parent 97195d3c
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
// 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);
}