git: fc36de571f11 - main - LinuxKPI: 802.11: adjust lower wake_queue locking

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Fri, 29 Aug 2025 13:18:57 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=fc36de571f11abda5cc68a4abd963053f676f8c5

commit fc36de571f11abda5cc68a4abd963053f676f8c5
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-08-29 07:39:01 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-08-29 13:18:41 +0000

    LinuxKPI: 802.11: adjust lower wake_queue locking
    
    In bc24342d96aa8 we added lower wake_queue locking.  There are paths,
    such as in rtw89 from a (*hw_scan_cancel)() that we can get to there and
    then would recursively acquire the wiphy lock which is not allowed.
    Adjust locking to a spin lock to match Linux driver expectations.
    
    Sponsored by:   The FreeBSD Foundation
    Fixes:          bc24342d96aa8
    MFC after:      3 days
---
 sys/compat/linuxkpi/common/src/linux_80211.c | 19 +++++++++++++++----
 sys/compat/linuxkpi/common/src/linux_80211.h |  1 +
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index e248588dd275..cf33a9e27788 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -6042,6 +6042,7 @@ linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops)
 
 	LKPI_80211_LHW_SCAN_LOCK_INIT(lhw);
 	LKPI_80211_LHW_TXQ_LOCK_INIT(lhw);
+	spin_lock_init(&lhw->txq_lock);
 	sx_init_flags(&lhw->lvif_sx, "lhw-lvif", SX_RECURSE | SX_DUPOK);
 	LKPI_80211_LHW_MC_LOCK_INIT(lhw);
 	TAILQ_INIT(&lhw->lvif_head);
@@ -6147,6 +6148,7 @@ linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw)
 	LKPI_80211_LHW_MC_UNLOCK(lhw);
 
 	/* Cleanup more of lhw here or in wiphy_free()? */
+	spin_lock_destroy(&lhw->txq_lock);
 	LKPI_80211_LHW_TXQ_LOCK_DESTROY(lhw);
 	LKPI_80211_LHW_SCAN_LOCK_DESTROY(lhw);
 	sx_destroy(&lhw->lvif_sx);
@@ -8124,21 +8126,30 @@ lkpi_ieee80211_wake_queues_locked(struct ieee80211_hw *hw)
 void
 linuxkpi_ieee80211_wake_queues(struct ieee80211_hw *hw)
 {
-	wiphy_lock(hw->wiphy);
+	struct lkpi_hw *lhw;
+	unsigned long flags;
+
+	lhw = HW_TO_LHW(hw);
+
+	spin_lock_irqsave(&lhw->txq_lock, flags);
 	lkpi_ieee80211_wake_queues_locked(hw);
-	wiphy_unlock(hw->wiphy);
+	spin_unlock_irqrestore(&lhw->txq_lock, flags);
 }
 
 void
 linuxkpi_ieee80211_wake_queue(struct ieee80211_hw *hw, int qnum)
 {
+	struct lkpi_hw *lhw;
+	unsigned long flags;
 
 	KASSERT(qnum < hw->queues, ("%s: qnum %d >= hw->queues %d, hw %p\n",
 	    __func__, qnum, hw->queues, hw));
 
-	wiphy_lock(hw->wiphy);
+	lhw = HW_TO_LHW(hw);
+
+	spin_lock_irqsave(&lhw->txq_lock, flags);
 	lkpi_ieee80211_wake_queues(hw, qnum);
-	wiphy_unlock(hw->wiphy);
+	spin_unlock_irqrestore(&lhw->txq_lock, flags);
 }
 
 /* This is just hardware queues. */
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h
index eaf6d804af4c..581148a94aa4 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.h
+++ b/sys/compat/linuxkpi/common/src/linux_80211.h
@@ -236,6 +236,7 @@ struct lkpi_hw {	/* name it mac80211_sc? */
 	struct mtx			txq_mtx;
 	uint32_t			txq_generation[IEEE80211_NUM_ACS];
 	TAILQ_HEAD(, lkpi_txq)		scheduled_txqs[IEEE80211_NUM_ACS];
+	spinlock_t			txq_lock;
 
 	/* Deferred RX path. */
 	struct task		rxq_task;