diff options
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 3 | ||||
-rw-r--r-- | include/net/mac80211.h | 31 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 10 |
3 files changed, 39 insertions, 5 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 7bbc455f5884..0780a1cc63a4 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -3069,8 +3069,7 @@ static int mac80211_hwsim_change_vif_links(struct ieee80211_hw *hw, for_each_set_bit(i, &add, IEEE80211_MLD_MAX_NUM_LINKS) { struct ieee80211_bss_conf *link_conf; - /* FIXME: figure out how to get the locking here */ - link_conf = rcu_dereference_protected(vif->link_conf[i], 1); + link_conf = link_conf_dereference_protected(vif, i); if (WARN_ON(!link_conf)) continue; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index bfa6a1625c5c..d9e7f62cc972 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -18,6 +18,7 @@ #include <linux/if_ether.h> #include <linux/skbuff.h> #include <linux/ieee80211.h> +#include <linux/lockdep.h> #include <net/cfg80211.h> #include <net/codel.h> #include <net/ieee80211_radiotap.h> @@ -1902,6 +1903,19 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif); /** + * lockdep_vif_mutex_held - for lockdep checks on link poiners + * @vif: the interface to check + */ +static inline bool lockdep_vif_mutex_held(struct ieee80211_vif *vif) +{ + return lockdep_is_held(&ieee80211_vif_to_wdev(vif)->mtx); +} + +#define link_conf_dereference_protected(vif, link_id) \ + rcu_dereference_protected((vif)->link_conf[link_id], \ + lockdep_vif_mutex_held(vif)) + +/** * enum ieee80211_key_flags - key flags * * These flags are used for communication about keys between the driver @@ -2266,13 +2280,24 @@ struct ieee80211_sta { u8 drv_priv[] __aligned(sizeof(void *)); }; -/* FIXME: check the locking correctly */ +#ifdef CONFIG_LOCKDEP +bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta); +#else +static inline bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta) +{ + return true; +} +#endif + +#define link_sta_dereference_protected(sta, link_id) \ + rcu_dereference_protected((sta)->link[link_id], \ + lockdep_sta_mutex_held(sta)) + #define for_each_sta_active_link(vif, sta, link_sta, link_id) \ for (link_id = 0; link_id < ARRAY_SIZE((sta)->link); link_id++) \ if ((!(vif)->active_links || \ (vif)->active_links & BIT(link_id)) && \ - ((link_sta) = rcu_dereference_protected((sta)->link[link_id],\ - 1))) + ((link_sta) = link_sta_dereference_protected(sta, link_id))) /** * enum sta_notify_cmd - sta notify command diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index bbf582a5702d..4875bd8af67c 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2871,3 +2871,13 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta, if (val) sta->sta.max_amsdu_subframes = 4 << val; } + +#ifdef CONFIG_LOCKDEP +bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta) +{ + struct sta_info *sta = container_of(pubsta, struct sta_info, sta); + + return lockdep_is_held(&sta->local->sta_mtx); +} +EXPORT_SYMBOL(lockdep_sta_mutex_held); +#endif |