summaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2017-10-29 11:51:08 +0200
committerJohannes Berg <johannes.berg@intel.com>2017-12-11 12:18:56 +0100
commit2316380f843dfd4cca5232a3b32dcb2b32b16722 (patch)
tree9c684113df3cbbdec404453ad55e53f9ce8ba623 /net/mac80211
parent9fef65443388a66a2c19835e2848a6ecf162710b (diff)
downloadlinux-2316380f843dfd4cca5232a3b32dcb2b32b16722.tar.gz
linux-2316380f843dfd4cca5232a3b32dcb2b32b16722.tar.bz2
linux-2316380f843dfd4cca5232a3b32dcb2b32b16722.zip
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>
Diffstat (limited to 'net/mac80211')
-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,
* telling the driver. New packets will not go through since
* the aggregation session is no longer OPERATIONAL.
*/
- synchronize_net();
+ if (!local->in_reconfig)
+ synchronize_net();
tid_tx->stop_initiator = reason == AGG_STOP_PEER_REQUEST ?
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)
flush_delayed_work(&local->roc_work);
flush_work(&local->hw_roc_done);
+ /* wait for all packet processing to be done */
+ synchronize_net();
+
ieee80211_reconfig(local);
rtnl_unlock();
}
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)
cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy, 0);
wake_up:
- if (local->in_reconfig) {
- local->in_reconfig = false;
- barrier();
-
- /* Restart deferred ROCs */
- mutex_lock(&local->mtx);
- ieee80211_start_next_roc(local);
- mutex_unlock(&local->mtx);
- }
if (local->monitors == local->open_count && local->monitors > 0)
ieee80211_add_virtual_monitor(local);
@@ -2146,6 +2137,16 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mutex_unlock(&local->sta_mtx);
}
+ if (local->in_reconfig) {
+ local->in_reconfig = false;
+ barrier();
+
+ /* Restart deferred ROCs */
+ mutex_lock(&local->mtx);
+ ieee80211_start_next_roc(local);
+ mutex_unlock(&local->mtx);
+ }
+
ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
IEEE80211_QUEUE_STOP_REASON_SUSPEND,
false);