The branch stable/14 has been updated by bz:

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

commit 8121f688bb550af894b4b1b3ff66dba283ac16d5
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2025-08-29 07:39:01 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2026-01-16 19:37:45 +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
    
    (cherry picked from commit fc36de571f11abda5cc68a4abd963053f676f8c5)
---
 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 7461b5db940a..17279f3caf6c 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -5959,6 +5959,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);
        TAILQ_INIT(&lhw->lvif_head);
        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
@@ -6058,6 +6059,7 @@ linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw)
        }
 
        /* 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);
@@ -8027,21 +8029,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 89afec1235bd..eb7bae811695 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.h
+++ b/sys/compat/linuxkpi/common/src/linux_80211.h
@@ -227,6 +227,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;

Reply via email to