summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c3
-rw-r--r--include/net/mac80211.h31
-rw-r--r--net/mac80211/sta_info.c10
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