6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maharaja Kennadyrajan maharaja.kennadyrajan@oss.qualcomm.com
[ Upstream commit 9975aeebe2908cdd552ee59607754755459fad52 ]
The ieee80211_csa_finish() function currently uses for_each_sdata_link() to iterate over links of sdata. However, this macro internally uses wiphy_dereference(), which expects the wiphy->mtx lock to be held. When ieee80211_csa_finish() is invoked under an RCU read-side critical section (e.g., under rcu_read_lock()), this leads to a warning from the RCU debugging framework.
WARNING: suspicious RCU usage net/mac80211/cfg.c:3830 suspicious rcu_dereference_protected() usage!
This warning is triggered because wiphy_dereference() is not safe to use without holding the wiphy mutex, and it is being used in an RCU context without the required locking.
Fix this by introducing and using a new macro, for_each_sdata_link_rcu(), which performs RCU-safe iteration over sdata links using list_for_each_entry_rcu() and rcu_dereference(). This ensures that the link pointers are accessed safely under RCU and eliminates the warning.
Fixes: f600832794c9 ("wifi: mac80211: restructure tx profile retrieval for MLO MBSSID") Signed-off-by: Maharaja Kennadyrajan maharaja.kennadyrajan@oss.qualcomm.com Link: https://patch.msgid.link/20250711033846.40455-1-maharaja.kennadyrajan@oss.qu... [unindent like the non-RCU macro] Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/cfg.c | 2 +- net/mac80211/ieee80211_i.h | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bc64c1b83a6e..18ad7ab1bb8c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3760,7 +3760,7 @@ void ieee80211_csa_finish(struct ieee80211_vif *vif, unsigned int link_id) */ struct ieee80211_link_data *iter;
- for_each_sdata_link(local, iter) { + for_each_sdata_link_rcu(local, iter) { if (iter->sdata == sdata || rcu_access_pointer(iter->conf->tx_bss_conf) != tx_bss_conf) continue; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 30809f0b35f7..f71d9eeb8abc 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1226,6 +1226,21 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) if ((_link = wiphy_dereference((_local)->hw.wiphy, \ ___sdata->link[___link_id])))
+/* + * for_each_sdata_link_rcu() must be used under RCU read lock. + */ +#define for_each_sdata_link_rcu(_local, _link) \ + /* outer loop just to define the variables ... */ \ + for (struct ieee80211_sub_if_data *___sdata = NULL; \ + !___sdata; \ + ___sdata = (void *)~0 /* always stop */) \ + list_for_each_entry_rcu(___sdata, &(_local)->interfaces, list) \ + if (ieee80211_sdata_running(___sdata)) \ + for (int ___link_id = 0; \ + ___link_id < ARRAY_SIZE((___sdata)->link); \ + ___link_id++) \ + if ((_link = rcu_dereference((___sdata)->link[___link_id]))) + #define for_each_link_data(sdata, __link) \ struct ieee80211_sub_if_data *__sdata = sdata; \ for (int __link_id = 0; \