aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-12-04 17:18:37 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-12-16 05:29:47 -0500
commite716251d776ce92eb5169522f565ada3deed2a2a (patch)
tree70615090a03c61e6f0d3f29b8b93e54cd8622f90 /net/mac80211
parentd778207b06ac1becd012eb689dafdf85feebb179 (diff)
mac80211: optimise mixed AP/VLAN station removal
Teach sta_info_flush() to optionally also remove stations from all VLANs associated with an AP interface to optimise the station removal (in particular, synchronize_net().) To not have to add the vlans argument throughout, do some refactoring. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/sta_info.c8
-rw-r--r--net/mac80211/sta_info.h8
3 files changed, 14 insertions, 6 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e11bdb63167a..18b56fb7911e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1097,9 +1097,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1097 if (old_probe_resp) 1097 if (old_probe_resp)
1098 kfree_rcu(old_probe_resp, rcu_head); 1098 kfree_rcu(old_probe_resp, rcu_head);
1099 1099
1100 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 1100 __sta_info_flush(sdata, true);
1101 sta_info_flush(vlan);
1102 sta_info_flush(sdata);
1103 synchronize_net(); 1101 synchronize_net();
1104 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 1102 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
1105 ieee80211_free_keys(vlan); 1103 ieee80211_free_keys(vlan);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 89d449d0de6d..4576ba0ff221 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -960,7 +960,7 @@ void sta_info_stop(struct ieee80211_local *local)
960} 960}
961 961
962 962
963int sta_info_flush(struct ieee80211_sub_if_data *sdata) 963int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans)
964{ 964{
965 struct ieee80211_local *local = sdata->local; 965 struct ieee80211_local *local = sdata->local;
966 struct sta_info *sta, *tmp; 966 struct sta_info *sta, *tmp;
@@ -969,9 +969,13 @@ int sta_info_flush(struct ieee80211_sub_if_data *sdata)
969 969
970 might_sleep(); 970 might_sleep();
971 971
972 WARN_ON(vlans && sdata->vif.type != NL80211_IFTYPE_AP);
973 WARN_ON(vlans && !sdata->bss);
974
972 mutex_lock(&local->sta_mtx); 975 mutex_lock(&local->sta_mtx);
973 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 976 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
974 if (sdata == sta->sdata) { 977 if (sdata == sta->sdata ||
978 (vlans && sdata->bss == sta->sdata->bss)) {
975 if (!WARN_ON(__sta_info_destroy_part1(sta))) 979 if (!WARN_ON(__sta_info_destroy_part1(sta)))
976 list_add(&sta->free_list, &free_list); 980 list_add(&sta->free_list, &free_list);
977 ret++; 981 ret++;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index f6081e574a28..d77ff7090630 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -613,8 +613,14 @@ void sta_info_stop(struct ieee80211_local *local);
613 * Returns the number of removed STA entries. 613 * Returns the number of removed STA entries.
614 * 614 *
615 * @sdata: sdata to remove all stations from 615 * @sdata: sdata to remove all stations from
616 * @vlans: if the given interface is an AP interface, also flush VLANs
616 */ 617 */
617int sta_info_flush(struct ieee80211_sub_if_data *sdata); 618int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans);
619
620static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata)
621{
622 return __sta_info_flush(sdata, false);
623}
618 624
619void sta_set_rate_info_tx(struct sta_info *sta, 625void sta_set_rate_info_tx(struct sta_info *sta,
620 const struct ieee80211_tx_rate *rate, 626 const struct ieee80211_tx_rate *rate,