git: 7614861463e6 - stable/14 - LinuxKPI: 802.11: adjust locking around lkpi_remove_chanctx()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 18 Apr 2025 14:37:14 UTC
The branch stable/14 has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=7614861463e6c26fdaaa79206b2bb0c79bb23683
commit 7614861463e6c26fdaaa79206b2bb0c79bb23683
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-04-08 16:35:20 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-04-18 14:36:01 +0000
LinuxKPI: 802.11: adjust locking around lkpi_remove_chanctx()
With the adjusted locking as a first step and the single code path
into lkpi_80211_mo_unassign_vif_chanctx() we also move the "setting
chnactx to NULL" into the caller to simplify the code.
Before we can adjust the other places touching vif->bss_conf.chanctx
we need to adjust the overall locking in LinuxKPI 802.11.
Sponsored by: The FreeBSD Foundation
PR: 280546
Tested by: Oleksandr Kryvulia (shuriku shurik.kiev.ua)
Tested by: Oleg Nauman (oleg.nauman gmail.com) [rtw88]
Differential Revision: https://reviews.freebsd.org/D49734
(cherry picked from commit 231168c7e77777f69a323bcd80a7956527d34548)
---
sys/compat/linuxkpi/common/src/linux_80211.c | 39 +++++++++++++---------
sys/compat/linuxkpi/common/src/linux_80211.h | 2 +-
.../linuxkpi/common/src/linux_80211_macops.c | 12 ++++---
3 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 43d5c5dc9deb..edd3b91dcecf 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -1735,24 +1735,27 @@ lkpi_80211_flush_tx(struct lkpi_hw *lhw, struct lkpi_sta *lsta)
static void
lkpi_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
- /* Take the chan ctx down. */
- if (vif->bss_conf.chanctx_conf != NULL) {
- struct lkpi_chanctx *lchanctx;
- struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ struct lkpi_chanctx *lchanctx;
- chanctx_conf = vif->bss_conf.chanctx_conf;
- /* Remove vif context. */
- lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->bss_conf, &vif->bss_conf.chanctx_conf);
- /* NB: vif->bss_conf.chanctx_conf is NULL now. */
+ chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf,
+ lockdep_is_held(&hw->wiphy->mtx));
- lkpi_hw_conf_idle(hw, true);
+ if (chanctx_conf == NULL)
+ return;
- /* Remove chan ctx. */
- lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
- vif->bss_conf.chanctx_conf = NULL;
- lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
- free(lchanctx, M_LKPI80211);
- }
+ /* Remove vif context. */
+ lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->bss_conf, chanctx_conf);
+
+ lkpi_hw_conf_idle(hw, true);
+
+ /* Remove chan ctx. */
+ lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
+
+ /* Cleanup. */
+ rcu_assign_pointer(vif->bss_conf.chanctx_conf, NULL);
+ lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
+ free(lchanctx, M_LKPI80211);
}
@@ -2183,7 +2186,9 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int
/* conf_tx */
+ wiphy_lock(hw->wiphy);
lkpi_remove_chanctx(hw, vif);
+ wiphy_unlock(hw->wiphy);
out:
LKPI_80211_LHW_UNLOCK(lhw);
@@ -2511,7 +2516,9 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i
/* conf_tx */
+ wiphy_lock(hw->wiphy);
lkpi_remove_chanctx(hw, vif);
+ wiphy_unlock(hw->wiphy);
error = EALREADY;
out:
@@ -3111,7 +3118,9 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int
/* conf_tx */
+ wiphy_lock(hw->wiphy);
lkpi_remove_chanctx(hw, vif);
+ wiphy_unlock(hw->wiphy);
error = EALREADY;
out:
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h
index c2d29b2dcc4b..c01a6cb0cd7c 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.h
+++ b/sys/compat/linuxkpi/common/src/linux_80211.h
@@ -425,7 +425,7 @@ int lkpi_80211_mo_config(struct ieee80211_hw *, uint32_t);
int lkpi_80211_mo_assign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *,
struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf *);
void lkpi_80211_mo_unassign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *,
- struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf **);
+ struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf *);
int lkpi_80211_mo_add_chanctx(struct ieee80211_hw *, struct ieee80211_chanctx_conf *);
void lkpi_80211_mo_change_chanctx(struct ieee80211_hw *,
struct ieee80211_chanctx_conf *, uint32_t);
diff --git a/sys/compat/linuxkpi/common/src/linux_80211_macops.c b/sys/compat/linuxkpi/common/src/linux_80211_macops.c
index e9f97914a4b1..ff3959340af7 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211_macops.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211_macops.c
@@ -467,21 +467,23 @@ out:
void
lkpi_80211_mo_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *conf, struct ieee80211_chanctx_conf **chanctx_conf)
+ struct ieee80211_bss_conf *conf, struct ieee80211_chanctx_conf *chanctx_conf)
{
struct lkpi_hw *lhw;
+ might_sleep();
+ lockdep_assert_wiphy(hw->wiphy);
+
lhw = HW_TO_LHW(hw);
if (lhw->ops->unassign_vif_chanctx == NULL)
return;
- if (*chanctx_conf == NULL)
+ if (chanctx_conf == NULL)
return;
LKPI_80211_TRACE_MO("hw %p vif %p bss_conf %p chanctx_conf %p",
- hw, vif, conf, *chanctx_conf);
- lhw->ops->unassign_vif_chanctx(hw, vif, conf, *chanctx_conf);
- *chanctx_conf = NULL;
+ hw, vif, conf, chanctx_conf);
+ lhw->ops->unassign_vif_chanctx(hw, vif, conf, chanctx_conf);
}