aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-12-04 16:46:11 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-12-16 05:29:45 -0500
commitd34ba2168a3c10e7301cca06069c39865b4c3ec6 (patch)
tree709e9c81eba18202588852e39d66fcf893334451 /net/mac80211/sta_info.c
parenta710c8160dd93e981163759aad754f758850273a (diff)
mac80211: don't delay station destruction
If we can assume that stations are never referenced by the driver after sta_state returns (and this is true since the previous iwlmvm patch and for all other drivers) then we don't need to delay station destruction, and don't need to play tricks with rcu_barrier() etc. This should speed up some scenarios like hostapd shutdown. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c58
1 files changed, 2 insertions, 56 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 557ac250ac10..7241f3229a27 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -99,23 +99,6 @@ static void cleanup_single_sta(struct sta_info *sta)
99 struct ieee80211_local *local = sdata->local; 99 struct ieee80211_local *local = sdata->local;
100 struct ps_data *ps; 100 struct ps_data *ps;
101 101
102 /*
103 * At this point, when being called as call_rcu callback,
104 * neither mac80211 nor the driver can reference this
105 * sta struct any more except by still existing timers
106 * associated with this station that we clean up below.
107 *
108 * Note though that this still uses the sdata and even
109 * calls the driver in AP and mesh mode, so interfaces
110 * of those types mush use call sta_info_flush_cleanup()
111 * (typically via sta_info_flush()) before deconfiguring
112 * the driver.
113 *
114 * In station mode, nothing happens here so it doesn't
115 * have to (and doesn't) do that, this is intentional to
116 * speed up roaming.
117 */
118
119 if (test_sta_flag(sta, WLAN_STA_PS_STA)) { 102 if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
120 if (sta->sdata->vif.type == NL80211_IFTYPE_AP || 103 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
121 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 104 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -160,37 +143,6 @@ static void cleanup_single_sta(struct sta_info *sta)
160 sta_info_free(local, sta); 143 sta_info_free(local, sta);
161} 144}
162 145
163void ieee80211_cleanup_sdata_stas(struct ieee80211_sub_if_data *sdata)
164{
165 struct sta_info *sta;
166
167 spin_lock_bh(&sdata->cleanup_stations_lock);
168 while (!list_empty(&sdata->cleanup_stations)) {
169 sta = list_first_entry(&sdata->cleanup_stations,
170 struct sta_info, list);
171 list_del(&sta->list);
172 spin_unlock_bh(&sdata->cleanup_stations_lock);
173
174 cleanup_single_sta(sta);
175
176 spin_lock_bh(&sdata->cleanup_stations_lock);
177 }
178
179 spin_unlock_bh(&sdata->cleanup_stations_lock);
180}
181
182static void free_sta_rcu(struct rcu_head *h)
183{
184 struct sta_info *sta = container_of(h, struct sta_info, rcu_head);
185 struct ieee80211_sub_if_data *sdata = sta->sdata;
186
187 spin_lock(&sdata->cleanup_stations_lock);
188 list_add_tail(&sta->list, &sdata->cleanup_stations);
189 spin_unlock(&sdata->cleanup_stations_lock);
190
191 ieee80211_queue_work(&sdata->local->hw, &sdata->cleanup_stations_wk);
192}
193
194/* protected by RCU */ 146/* protected by RCU */
195struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, 147struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
196 const u8 *addr) 148 const u8 *addr)
@@ -909,7 +861,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
909 ieee80211_sta_debugfs_remove(sta); 861 ieee80211_sta_debugfs_remove(sta);
910 ieee80211_recalc_min_chandef(sdata); 862 ieee80211_recalc_min_chandef(sdata);
911 863
912 call_rcu(&sta->rcu_head, free_sta_rcu); 864 cleanup_single_sta(sta);
913 865
914 return 0; 866 return 0;
915} 867}
@@ -979,7 +931,7 @@ void sta_info_stop(struct ieee80211_local *local)
979} 931}
980 932
981 933
982int sta_info_flush_defer(struct ieee80211_sub_if_data *sdata) 934int sta_info_flush(struct ieee80211_sub_if_data *sdata)
983{ 935{
984 struct ieee80211_local *local = sdata->local; 936 struct ieee80211_local *local = sdata->local;
985 struct sta_info *sta, *tmp; 937 struct sta_info *sta, *tmp;
@@ -999,12 +951,6 @@ int sta_info_flush_defer(struct ieee80211_sub_if_data *sdata)
999 return ret; 951 return ret;
1000} 952}
1001 953
1002void sta_info_flush_cleanup(struct ieee80211_sub_if_data *sdata)
1003{
1004 ieee80211_cleanup_sdata_stas(sdata);
1005 cancel_work_sync(&sdata->cleanup_stations_wk);
1006}
1007
1008void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, 954void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
1009 unsigned long exp_time) 955 unsigned long exp_time)
1010{ 956{