git: a8a47a41775b - main - LinuxKPI: 802.11: add a lchanctx list to lhw
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 11 Apr 2025 21:26:24 UTC
The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=a8a47a41775b0320606f90b3ac2048bc23494615 commit a8a47a41775b0320606f90b3ac2048bc23494615 Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2025-04-08 23:05:43 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2025-04-11 21:26:05 +0000 LinuxKPI: 802.11: add a lchanctx list to lhw While we are currently only supporting a single VAP (vif) it is less of a trouble but in order to get locking and rcu accesses [from drivers] more right add a list for all chanctx_conf we have for one hw. Use that list in the iterator function to avoid having to lock the vif but not protecting the chanctx list (against a parallel removal) due to different locking. Sponsored by: The FreeBSD Foundation PR: 280546 MFC after: 3 days Tested by: Oleksandr Kryvulia (shuriku shurik.kiev.ua) Tested by: Oleg Nauman (oleg.nauman gmail.com) [rtw88] Differential Revision: https://reviews.freebsd.org/D49734 --- sys/compat/linuxkpi/common/src/linux_80211.c | 39 ++++++++++++++++++---------- sys/compat/linuxkpi/common/src/linux_80211.h | 5 ++++ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 891714fb75db..65f203c0eec9 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -1757,6 +1757,7 @@ lkpi_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif) /* Cleanup. */ rcu_assign_pointer(vif->bss_conf.chanctx_conf, NULL); lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf); + list_del(&lchanctx->entry); free(lchanctx, M_LKPI80211); } @@ -1943,6 +1944,7 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int goto out; } + list_add_rcu(&lchanctx->entry, &lhw->lchanctx_list); rcu_assign_pointer(vif->bss_conf.chanctx_conf, chanctx_conf); /* Assign vif chanctx. */ @@ -1957,6 +1959,7 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int lkpi_80211_mo_remove_chanctx(hw, chanctx_conf); rcu_assign_pointer(vif->bss_conf.chanctx_conf, NULL); lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf); + list_del(&lchanctx->entry); free(lchanctx, M_LKPI80211); goto out; } @@ -5458,6 +5461,9 @@ linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops) TAILQ_INIT(&lhw->scheduled_txqs[ac]); } + /* Chanctx_conf */ + INIT_LIST_HEAD(&lhw->lchanctx_list); + /* Deferred RX path. */ LKPI_80211_LHW_RXQ_LOCK_INIT(lhw); TASK_INIT(&lhw->rxq_task, 0, lkpi_80211_lhw_rxq_task, lhw); @@ -5521,6 +5527,22 @@ linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw) __func__, lhw, mbufq_len(&lhw->rxq))); LKPI_80211_LHW_RXQ_LOCK_DESTROY(lhw); + /* Chanctx_conf. */ + if (!list_empty_careful(&lhw->lchanctx_list)) { + struct lkpi_chanctx *lchanctx, *next; + struct ieee80211_chanctx_conf *chanctx_conf; + + list_for_each_entry_safe(lchanctx, next, &lhw->lchanctx_list, entry) { + if (lchanctx->added_to_drv) { + /* In reality we should panic? */ + chanctx_conf = &lchanctx->chanctx_conf; + lkpi_80211_mo_remove_chanctx(hw, chanctx_conf); + } + list_del(&lchanctx->entry); + free(lchanctx, M_LKPI80211); + } + } + /* Cleanup more of lhw here or in wiphy_free()? */ LKPI_80211_LHW_TXQ_LOCK_DESTROY(lhw); LKPI_80211_LHW_SCAN_LOCK_DESTROY(lhw); @@ -5955,8 +5977,6 @@ linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *hw, void *arg) { struct lkpi_hw *lhw; - struct lkpi_vif *lvif; - struct ieee80211_vif *vif; struct lkpi_chanctx *lchanctx; KASSERT(hw != NULL && iterfunc != NULL, @@ -5964,22 +5984,13 @@ linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *hw, lhw = HW_TO_LHW(hw); - IMPROVE("lchanctx should be its own list somewhere"); - - LKPI_80211_LHW_LVIF_LOCK(lhw); - TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) { - - vif = LVIF_TO_VIF(lvif); - if (vif->bss_conf.chanctx_conf == NULL) /* XXX-BZ; FIXME see IMPROVE above. */ - continue; - - lchanctx = CHANCTX_CONF_TO_LCHANCTX(vif->bss_conf.chanctx_conf); + rcu_read_lock(); + list_for_each_entry_rcu(lchanctx, &lhw->lchanctx_list, entry) { if (!lchanctx->added_to_drv) continue; - iterfunc(hw, &lchanctx->chanctx_conf, arg); } - LKPI_80211_LHW_LVIF_UNLOCK(lhw); + rcu_read_unlock(); } void diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h index 7028e05e9b20..da377280b1c0 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.h +++ b/sys/compat/linuxkpi/common/src/linux_80211.h @@ -216,6 +216,8 @@ struct lkpi_hw { /* name it mac80211_sc? */ TAILQ_HEAD(, lkpi_vif) lvif_head; struct sx lvif_sx; + struct list_head lchanctx_list; + struct mtx txq_mtx; uint32_t txq_generation[IEEE80211_NUM_ACS]; TAILQ_HEAD(, lkpi_txq) scheduled_txqs[IEEE80211_NUM_ACS]; @@ -282,7 +284,10 @@ struct lkpi_hw { /* name it mac80211_sc? */ #define HW_TO_LHW(_hw) container_of(_hw, struct lkpi_hw, hw) struct lkpi_chanctx { + struct list_head entry; + bool added_to_drv; /* Managed by MO */ + struct ieee80211_chanctx_conf chanctx_conf __aligned(CACHE_LINE_SIZE); }; #define LCHANCTX_TO_CHANCTX_CONF(_lchanctx) \