The branch main has been updated by bz:

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

commit a8a47a41775b0320606f90b3ac2048bc23494615
Author:     Bjoern A. Zeeb <b...@freebsd.org>
AuthorDate: 2025-04-08 23:05:43 +0000
Commit:     Bjoern A. Zeeb <b...@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)             \

Reply via email to