Search Linux Wireless

[PATCH 7/8] mac80211: optimise mixed AP/VLAN station removal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Johannes Berg <johannes.berg@xxxxxxxxx>

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@xxxxxxxxx>
---
 net/mac80211/cfg.c      | 4 +---
 net/mac80211/sta_info.c | 8 ++++++--
 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 f47c7c0..b045deb2 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)
 	if (old_probe_resp)
 		kfree_rcu(old_probe_resp, rcu_head);
 
-	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
-		sta_info_flush(vlan);
-	sta_info_flush(sdata);
+	__sta_info_flush(sdata, true);
 	synchronize_net();
 	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
 		ieee80211_free_keys(vlan);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 89d449d..4576ba0 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)
 }
 
 
-int sta_info_flush(struct ieee80211_sub_if_data *sdata)
+int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct sta_info *sta, *tmp;
@@ -969,9 +969,13 @@ int sta_info_flush(struct ieee80211_sub_if_data *sdata)
 
 	might_sleep();
 
+	WARN_ON(vlans && sdata->vif.type != NL80211_IFTYPE_AP);
+	WARN_ON(vlans && !sdata->bss);
+
 	mutex_lock(&local->sta_mtx);
 	list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
-		if (sdata == sta->sdata) {
+		if (sdata == sta->sdata ||
+		    (vlans && sdata->bss == sta->sdata->bss)) {
 			if (!WARN_ON(__sta_info_destroy_part1(sta)))
 				list_add(&sta->free_list, &free_list);
 			ret++;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 1f20664..82043e85 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -612,8 +612,14 @@ void sta_info_stop(struct ieee80211_local *local);
  * Returns the number of removed STA entries.
  *
  * @sdata: sdata to remove all stations from
+ * @vlans: if the given interface is an AP interface, also flush VLANs
  */
-int sta_info_flush(struct ieee80211_sub_if_data *sdata);
+int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans);
+
+static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata)
+{
+	return __sta_info_flush(sdata, false);
+}
 
 void sta_set_rate_info_tx(struct sta_info *sta,
 			  const struct ieee80211_tx_rate *rate,
-- 
1.8.4.rc3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux