summaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-12-04 22:39:17 +0100
committerJohannes Berg <johannes.berg@intel.com>2013-12-16 11:29:44 +0100
commit6a9d1b91f34df1935bc0ad98114801a44db0f98c (patch)
treeecf4637a32c57786a6ac468be5bc392bb28e779d /net/mac80211/sta_info.c
parentMerge remote-tracking branch 'wireless-next/master' into mac80211-next (diff)
downloadlinux-6a9d1b91f34df1935bc0ad98114801a44db0f98c.tar.xz
linux-6a9d1b91f34df1935bc0ad98114801a44db0f98c.zip
mac80211: add pre-RCU-sync sta removal driver operation
Currently, mac80211 allows drivers to keep RCU-protected station references that are cleared when the station is removed from the driver and consequently needs to synchronize twice, once before removing the station from the driver (so it can guarantee that the station is no longer used in TX towards the driver) and once after the station is removed from the driver. Add a new pre-RCU-synchronisation station removal operation to the API to allow drivers to clear/invalidate their RCU-protected station pointers before the RCU synchronisation. This will allow removing the second synchronisation by changing the driver API so that the driver may no longer assume a valid RCU-protected pointer after sta_remove/sta_state returns. The alternative to this would be to synchronize_rcu() in all the drivers that currently rely on this behaviour (only iwlmvm) but that would defeat the purpose. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 8ae37f60d60c..1e147742eccf 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -873,6 +873,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
list_del_rcu(&sta->list);
+ drv_sta_pre_rcu_remove(local, sta->sdata, sta);
+
/* this always calls synchronize_net() */
ieee80211_free_sta_keys(local, sta);