Commit 65fd846c authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: add vif/sta link RCU dereference macros

Add macros (and an exported function) to allow checking some
link RCU protected accesses that are happening in callbacks
from mac80211 and are thus under the correct lock.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 5fc8cea9
...@@ -3069,8 +3069,7 @@ static int mac80211_hwsim_change_vif_links(struct ieee80211_hw *hw, ...@@ -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) { for_each_set_bit(i, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
struct ieee80211_bss_conf *link_conf; struct ieee80211_bss_conf *link_conf;
/* FIXME: figure out how to get the locking here */ link_conf = link_conf_dereference_protected(vif, i);
link_conf = rcu_dereference_protected(vif->link_conf[i], 1);
if (WARN_ON(!link_conf)) if (WARN_ON(!link_conf))
continue; continue;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/ieee80211.h> #include <linux/ieee80211.h>
#include <linux/lockdep.h>
#include <net/cfg80211.h> #include <net/cfg80211.h>
#include <net/codel.h> #include <net/codel.h>
#include <net/ieee80211_radiotap.h> #include <net/ieee80211_radiotap.h>
...@@ -1901,6 +1902,19 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); ...@@ -1901,6 +1902,19 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev);
*/ */
struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif); 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 * enum ieee80211_key_flags - key flags
* *
...@@ -2266,13 +2280,24 @@ struct ieee80211_sta { ...@@ -2266,13 +2280,24 @@ struct ieee80211_sta {
u8 drv_priv[] __aligned(sizeof(void *)); 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) \ #define for_each_sta_active_link(vif, sta, link_sta, link_id) \
for (link_id = 0; link_id < ARRAY_SIZE((sta)->link); link_id++) \ for (link_id = 0; link_id < ARRAY_SIZE((sta)->link); link_id++) \
if ((!(vif)->active_links || \ if ((!(vif)->active_links || \
(vif)->active_links & BIT(link_id)) && \ (vif)->active_links & BIT(link_id)) && \
((link_sta) = rcu_dereference_protected((sta)->link[link_id],\ ((link_sta) = link_sta_dereference_protected(sta, link_id)))
1)))
/** /**
* enum sta_notify_cmd - sta notify command * enum sta_notify_cmd - sta notify command
......
...@@ -2871,3 +2871,13 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta, ...@@ -2871,3 +2871,13 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,
if (val) if (val)
sta->sta.max_amsdu_subframes = 4 << 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment