diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-12-04 17:18:37 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-12-16 05:29:47 -0500 |
commit | e716251d776ce92eb5169522f565ada3deed2a2a (patch) | |
tree | 70615090a03c61e6f0d3f29b8b93e54cd8622f90 /net/mac80211 | |
parent | d778207b06ac1becd012eb689dafdf85feebb179 (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.c | 4 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 8 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 8 |
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 | ||
963 | int sta_info_flush(struct ieee80211_sub_if_data *sdata) | 963 | int __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 | */ |
617 | int sta_info_flush(struct ieee80211_sub_if_data *sdata); | 618 | int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans); |
619 | |||
620 | static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata) | ||
621 | { | ||
622 | return __sta_info_flush(sdata, false); | ||
623 | } | ||
618 | 624 | ||
619 | void sta_set_rate_info_tx(struct sta_info *sta, | 625 | void sta_set_rate_info_tx(struct sta_info *sta, |
620 | const struct ieee80211_tx_rate *rate, | 626 | const struct ieee80211_tx_rate *rate, |