aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-01-07 08:42:39 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-01-14 03:31:18 -0500
commit3b24f4c65386dc0f2efb41027bc6e410ea2c0049 (patch)
treeb1015543f700d19b63f3674f214e20e14e67459d
parent0efbb786f1a3e13d28861ff41aae8dc4be314608 (diff)
mac80211: let flush() drop packets when possible
When roaming / suspending, it makes no sense to wait until the transmit queues of the device are empty. In extreme condition they can be starved (VO saturating the air), but even in regular cases, it is pointless to delay the roaming because the low level driver is trying to send packets to an AP which is far away. We'd rather drop these packets and let TCP retransmit if needed. This will allow to speed up the roaming. For suspend, the explanation is even more trivial. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/mlme.c15
-rw-r--r--net/mac80211/offchannel.c4
-rw-r--r--net/mac80211/pm.c2
-rw-r--r--net/mac80211/scan.c4
-rw-r--r--net/mac80211/tdls.c6
-rw-r--r--net/mac80211/tx.c2
-rw-r--r--net/mac80211/util.c8
10 files changed, 27 insertions, 22 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 169665835b6c..9ccecb405ede 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3665,7 +3665,7 @@ static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev,
3665 * queues. 3665 * queues.
3666 */ 3666 */
3667 synchronize_net(); 3667 synchronize_net();
3668 ieee80211_flush_queues(local, sdata); 3668 ieee80211_flush_queues(local, sdata, false);
3669 3669
3670 /* restore the normal QoS parameters 3670 /* restore the normal QoS parameters
3671 * (unconditionally to avoid races) 3671 * (unconditionally to avoid races)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4f45cab8b7f1..91878ef5069a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1882,10 +1882,10 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
1882void ieee80211_add_pending_skbs(struct ieee80211_local *local, 1882void ieee80211_add_pending_skbs(struct ieee80211_local *local,
1883 struct sk_buff_head *skbs); 1883 struct sk_buff_head *skbs);
1884void ieee80211_flush_queues(struct ieee80211_local *local, 1884void ieee80211_flush_queues(struct ieee80211_local *local,
1885 struct ieee80211_sub_if_data *sdata); 1885 struct ieee80211_sub_if_data *sdata, bool drop);
1886void __ieee80211_flush_queues(struct ieee80211_local *local, 1886void __ieee80211_flush_queues(struct ieee80211_local *local,
1887 struct ieee80211_sub_if_data *sdata, 1887 struct ieee80211_sub_if_data *sdata,
1888 unsigned int queues); 1888 unsigned int queues, bool drop);
1889 1889
1890void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1890void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1891 u16 transaction, u16 auth_alg, u16 status, 1891 u16 transaction, u16 auth_alg, u16 status,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 417355390873..677422e11e07 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -93,7 +93,7 @@ static u32 __ieee80211_idle_on(struct ieee80211_local *local)
93 if (local->hw.conf.flags & IEEE80211_CONF_IDLE) 93 if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
94 return 0; 94 return 0;
95 95
96 ieee80211_flush_queues(local, NULL); 96 ieee80211_flush_queues(local, NULL, false);
97 97
98 local->hw.conf.flags |= IEEE80211_CONF_IDLE; 98 local->hw.conf.flags |= IEEE80211_CONF_IDLE;
99 return IEEE80211_CONF_CHANGE_IDLE; 99 return IEEE80211_CONF_CHANGE_IDLE;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8354bedc858a..c0711082a2b8 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1604,7 +1604,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
1604 } else { 1604 } else {
1605 ieee80211_send_nullfunc(local, sdata, 1); 1605 ieee80211_send_nullfunc(local, sdata, 1);
1606 /* Flush to get the tx status of nullfunc frame */ 1606 /* Flush to get the tx status of nullfunc frame */
1607 ieee80211_flush_queues(local, sdata); 1607 ieee80211_flush_queues(local, sdata, false);
1608 } 1608 }
1609 } 1609 }
1610 1610
@@ -2011,18 +2011,23 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
2011 /* disable per-vif ps */ 2011 /* disable per-vif ps */
2012 ieee80211_recalc_ps_vif(sdata); 2012 ieee80211_recalc_ps_vif(sdata);
2013 2013
2014 /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ 2014 /*
2015 * drop any frame before deauth/disassoc, this can be data or
2016 * management frame. Since we are disconnecting, we should not
2017 * insist sending these frames which can take time and delay
2018 * the disconnection and possible the roaming.
2019 */
2015 if (tx) 2020 if (tx)
2016 ieee80211_flush_queues(local, sdata); 2021 ieee80211_flush_queues(local, sdata, true);
2017 2022
2018 /* deauthenticate/disassociate now */ 2023 /* deauthenticate/disassociate now */
2019 if (tx || frame_buf) 2024 if (tx || frame_buf)
2020 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, 2025 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
2021 reason, tx, frame_buf); 2026 reason, tx, frame_buf);
2022 2027
2023 /* flush out frame */ 2028 /* flush out frame - make sure the deauth was actually sent */
2024 if (tx) 2029 if (tx)
2025 ieee80211_flush_queues(local, sdata); 2030 ieee80211_flush_queues(local, sdata, false);
2026 2031
2027 /* clear bssid only after building the needed mgmt frames */ 2032 /* clear bssid only after building the needed mgmt frames */
2028 memset(ifmgd->bssid, 0, ETH_ALEN); 2033 memset(ifmgd->bssid, 0, ETH_ALEN);
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index ff20b2ebdb30..683f0e3cb124 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -121,7 +121,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
121 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 121 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, 122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
123 false); 123 false);
124 ieee80211_flush_queues(local, NULL); 124 ieee80211_flush_queues(local, NULL, false);
125 125
126 mutex_lock(&local->iflist_mtx); 126 mutex_lock(&local->iflist_mtx);
127 list_for_each_entry(sdata, &local->interfaces, list) { 127 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -398,7 +398,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
398 ieee80211_roc_notify_destroy(roc, !roc->abort); 398 ieee80211_roc_notify_destroy(roc, !roc->abort);
399 399
400 if (started && !on_channel) { 400 if (started && !on_channel) {
401 ieee80211_flush_queues(local, NULL); 401 ieee80211_flush_queues(local, NULL, false);
402 402
403 local->tmp_channel = NULL; 403 local->tmp_channel = NULL;
404 ieee80211_hw_config(local, 0); 404 ieee80211_hw_config(local, 0);
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 4c5192e0d66c..8c8c67819072 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -41,7 +41,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
41 /* flush out all packets */ 41 /* flush out all packets */
42 synchronize_net(); 42 synchronize_net();
43 43
44 ieee80211_flush_queues(local, NULL); 44 ieee80211_flush_queues(local, NULL, true);
45 45
46 local->quiescing = true; 46 local->quiescing = true;
47 /* make quiescing visible to timers everywhere */ 47 /* make quiescing visible to timers everywhere */
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index ae842678b629..844fb5f7910e 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -416,7 +416,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local,
416 ieee80211_offchannel_stop_vifs(local); 416 ieee80211_offchannel_stop_vifs(local);
417 417
418 /* ensure nullfunc is transmitted before leaving operating channel */ 418 /* ensure nullfunc is transmitted before leaving operating channel */
419 ieee80211_flush_queues(local, NULL); 419 ieee80211_flush_queues(local, NULL, false);
420 420
421 ieee80211_configure_filter(local); 421 ieee80211_configure_filter(local);
422 422
@@ -805,7 +805,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local,
805 ieee80211_offchannel_stop_vifs(local); 805 ieee80211_offchannel_stop_vifs(local);
806 806
807 if (local->ops->flush) { 807 if (local->ops->flush) {
808 ieee80211_flush_queues(local, NULL); 808 ieee80211_flush_queues(local, NULL, false);
809 *next_delay = 0; 809 *next_delay = 0;
810 } else 810 } else
811 *next_delay = HZ / 10; 811 *next_delay = HZ / 10;
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 55ddd77b865d..159ebf1304b2 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -912,7 +912,7 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
912 rcu_read_unlock(); 912 rcu_read_unlock();
913 } 913 }
914 914
915 ieee80211_flush_queues(local, sdata); 915 ieee80211_flush_queues(local, sdata, false);
916 916
917 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, 917 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
918 dialog_token, status_code, 918 dialog_token, status_code,
@@ -952,7 +952,7 @@ ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
952 */ 952 */
953 ieee80211_stop_vif_queues(local, sdata, 953 ieee80211_stop_vif_queues(local, sdata,
954 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN); 954 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
955 ieee80211_flush_queues(local, sdata); 955 ieee80211_flush_queues(local, sdata, false);
956 956
957 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, 957 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
958 dialog_token, status_code, 958 dialog_token, status_code,
@@ -1098,7 +1098,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
1098 */ 1098 */
1099 tasklet_kill(&local->tx_pending_tasklet); 1099 tasklet_kill(&local->tx_pending_tasklet);
1100 /* flush a potentially queued teardown packet */ 1100 /* flush a potentially queued teardown packet */
1101 ieee80211_flush_queues(local, sdata); 1101 ieee80211_flush_queues(local, sdata, false);
1102 1102
1103 ret = sta_info_destroy_addr(sdata, peer); 1103 ret = sta_info_destroy_addr(sdata, peer);
1104 break; 1104 break;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index da7f352a2b16..02ed6f60629a 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3155,7 +3155,7 @@ int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)
3155 } 3155 }
3156 3156
3157 queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]); 3157 queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]);
3158 __ieee80211_flush_queues(local, sdata, queues); 3158 __ieee80211_flush_queues(local, sdata, queues, false);
3159 3159
3160 sta->reserved_tid = tid; 3160 sta->reserved_tid = tid;
3161 3161
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ad8cb4fb441e..83ba6cd9cf8d 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -578,7 +578,7 @@ ieee80211_get_vif_queues(struct ieee80211_local *local,
578 578
579void __ieee80211_flush_queues(struct ieee80211_local *local, 579void __ieee80211_flush_queues(struct ieee80211_local *local,
580 struct ieee80211_sub_if_data *sdata, 580 struct ieee80211_sub_if_data *sdata,
581 unsigned int queues) 581 unsigned int queues, bool drop)
582{ 582{
583 if (!local->ops->flush) 583 if (!local->ops->flush)
584 return; 584 return;
@@ -594,7 +594,7 @@ void __ieee80211_flush_queues(struct ieee80211_local *local,
594 IEEE80211_QUEUE_STOP_REASON_FLUSH, 594 IEEE80211_QUEUE_STOP_REASON_FLUSH,
595 false); 595 false);
596 596
597 drv_flush(local, sdata, queues, false); 597 drv_flush(local, sdata, queues, drop);
598 598
599 ieee80211_wake_queues_by_reason(&local->hw, queues, 599 ieee80211_wake_queues_by_reason(&local->hw, queues,
600 IEEE80211_QUEUE_STOP_REASON_FLUSH, 600 IEEE80211_QUEUE_STOP_REASON_FLUSH,
@@ -602,9 +602,9 @@ void __ieee80211_flush_queues(struct ieee80211_local *local,
602} 602}
603 603
604void ieee80211_flush_queues(struct ieee80211_local *local, 604void ieee80211_flush_queues(struct ieee80211_local *local,
605 struct ieee80211_sub_if_data *sdata) 605 struct ieee80211_sub_if_data *sdata, bool drop)
606{ 606{
607 __ieee80211_flush_queues(local, sdata, 0); 607 __ieee80211_flush_queues(local, sdata, 0, drop);
608} 608}
609 609
610void ieee80211_stop_vif_queues(struct ieee80211_local *local, 610void ieee80211_stop_vif_queues(struct ieee80211_local *local,