summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com>2025-07-18 11:38:35 +0530
committerJohannes Berg <johannes.berg@intel.com>2025-07-18 14:08:11 +0200
commit4e1916dec9850cd49dd5792200ab649061cbedc1 (patch)
treefbcdd09d5df0e409d83327d0742b6baf388dabd2
parentf562f6a5899d91940fd5ef78e3f6042f56abe3e2 (diff)
wifi: mac80211: Add link iteration macro for link data with rcu_dereference
Currently, the existing macro for_each_link_data() uses sdata_dereference() which requires the wiphy lock. This lock cannot be used in atomic or RCU read-side contexts, such as in the RX path. Introduce a new macro, for_each_link_data_rcu(), that iterates over link of sdata using rcu_dereference(), making it safe to use in RCU contexts. This allows callers to access link data without requiring the wiphy lock. The macro takes into account the vif.valid_links bitmap and ensures only valid links are accessed safely. Callers are responsible for ensuring that rcu_read_lock() is held when using this macro. Signed-off-by: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com> Link: https://patch.msgid.link/20250718060837.59371-3-maharaja.kennadyrajan@oss.qualcomm.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/ieee80211_i.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7c18c51966d0..9c0603eb580f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1252,6 +1252,19 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
((__link) = sdata_dereference((__sdata)->link[__link_id], \
(__sdata))))
+/*
+ * for_each_link_data_rcu should be used under RCU read lock.
+ */
+#define for_each_link_data_rcu(sdata, __link) \
+ /* outer loop just to define the variable ... */ \
+ for (struct ieee80211_sub_if_data *__sdata = (sdata); __sdata; \
+ __sdata = NULL /* always stop */) \
+ for (int __link_id = 0; \
+ __link_id < ARRAY_SIZE((__sdata)->link); __link_id++) \
+ if ((!(__sdata)->vif.valid_links || \
+ (__sdata)->vif.valid_links & BIT(__link_id)) && \
+ ((__link) = rcu_dereference((__sdata)->link[__link_id]))) \
+
static inline int
ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems,
struct cfg80211_rnr_elems *rnr_elems,