aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2017-10-29 05:51:08 -0400
committerJohannes Berg <johannes.berg@intel.com>2017-12-11 06:18:56 -0500
commit2316380f843dfd4cca5232a3b32dcb2b32b16722 (patch)
tree9c684113df3cbbdec404453ad55e53f9ce8ba623
parent9fef65443388a66a2c19835e2848a6ecf162710b (diff)
mac80211: call synchronize_net once in the restart flow
Currently the restart flow enables RX back, and then proceeds to tear down RX and TX aggregations. The TX aggregation tear down calls synchronize_net(), which waits for packet receiving to be done. This is done for every session, while RX processing is already active, and in some reproductions it takes up to 3 seconds. Add a call once in the restart_work, before we have traffic active again, and remove the subsequent calls when tearing down the aggregation. This requires to move down the code that turns off the reconfig flag in order to be able to test it in _ieee80211_stop_tx_ba_session(). Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/agg-tx.c3
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/util.c19
3 files changed, 15 insertions, 10 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index a04df962129c..595c662a61e8 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -392,7 +392,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
392 * telling the driver. New packets will not go through since 392 * telling the driver. New packets will not go through since
393 * the aggregation session is no longer OPERATIONAL. 393 * the aggregation session is no longer OPERATIONAL.
394 */ 394 */
395 synchronize_net(); 395 if (!local->in_reconfig)
396 synchronize_net();
396 397
397 tid_tx->stop_initiator = reason == AGG_STOP_PEER_REQUEST ? 398 tid_tx->stop_initiator = reason == AGG_STOP_PEER_REQUEST ?
398 WLAN_BACK_RECIPIENT : 399 WLAN_BACK_RECIPIENT :
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e054a2fd8d38..0785d04a80bc 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -263,6 +263,9 @@ static void ieee80211_restart_work(struct work_struct *work)
263 flush_delayed_work(&local->roc_work); 263 flush_delayed_work(&local->roc_work);
264 flush_work(&local->hw_roc_done); 264 flush_work(&local->hw_roc_done);
265 265
266 /* wait for all packet processing to be done */
267 synchronize_net();
268
266 ieee80211_reconfig(local); 269 ieee80211_reconfig(local);
267 rtnl_unlock(); 270 rtnl_unlock();
268} 271}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index d57e5f6bd8b6..1f82191ce601 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2110,15 +2110,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
2110 cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy, 0); 2110 cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy, 0);
2111 2111
2112 wake_up: 2112 wake_up:
2113 if (local->in_reconfig) {
2114 local->in_reconfig = false;
2115 barrier();
2116
2117 /* Restart deferred ROCs */
2118 mutex_lock(&local->mtx);
2119 ieee80211_start_next_roc(local);
2120 mutex_unlock(&local->mtx);
2121 }
2122 2113
2123 if (local->monitors == local->open_count && local->monitors > 0) 2114 if (local->monitors == local->open_count && local->monitors > 0)
2124 ieee80211_add_virtual_monitor(local); 2115 ieee80211_add_virtual_monitor(local);
@@ -2146,6 +2137,16 @@ int ieee80211_reconfig(struct ieee80211_local *local)
2146 mutex_unlock(&local->sta_mtx); 2137 mutex_unlock(&local->sta_mtx);
2147 } 2138 }
2148 2139
2140 if (local->in_reconfig) {
2141 local->in_reconfig = false;
2142 barrier();
2143
2144 /* Restart deferred ROCs */
2145 mutex_lock(&local->mtx);
2146 ieee80211_start_next_roc(local);
2147 mutex_unlock(&local->mtx);
2148 }
2149
2149 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 2150 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
2150 IEEE80211_QUEUE_STOP_REASON_SUSPEND, 2151 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
2151 false); 2152 false);