git: fc36de571f11 - main - LinuxKPI: 802.11: adjust lower wake_queue locking
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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;