Add patches to improve mac80211 latency and throughput (rhbz 830151)

This commit is contained in:
Josh Boyer 2013-02-01 09:34:24 -05:00
parent 72b2eb9d00
commit f63d946a67
3 changed files with 254 additions and 0 deletions

View File

@ -0,0 +1,103 @@
From 70277f47b58b174a6b0b891dcd06ae5125afb73b Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Thu, 20 Dec 2012 14:31:51 +0100
Subject: [PATCH] iwlegacy: add flush callback
Dump implementation of flush, which just wait until all TX queues
become empty.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/net/wireless/iwlegacy/3945-mac.c | 1 +
drivers/net/wireless/iwlegacy/4965-mac.c | 1 +
drivers/net/wireless/iwlegacy/common.c | 36 ++++++++++++++++++++++++++++++
drivers/net/wireless/iwlegacy/common.h | 1 +
4 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index d604b40..962400a 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -3474,6 +3474,7 @@ struct ieee80211_ops il3945_mac_ops = {
.sta_add = il3945_mac_sta_add,
.sta_remove = il_mac_sta_remove,
.tx_last_beacon = il_mac_tx_last_beacon,
+ .flush = il_mac_flush,
};
static int
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 6a86ed4..c40020c 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -6308,6 +6308,7 @@ const struct ieee80211_ops il4965_mac_ops = {
.sta_remove = il_mac_sta_remove,
.channel_switch = il4965_mac_channel_switch,
.tx_last_beacon = il_mac_tx_last_beacon,
+ .flush = il_mac_flush,
};
static int
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 7e16d10..56b8021 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -4707,6 +4707,42 @@ out:
}
EXPORT_SYMBOL(il_mac_change_interface);
+void
+il_mac_flush(struct ieee80211_hw *hw, bool drop)
+{
+ struct il_priv *il = hw->priv;
+ unsigned long timeout = jiffies + msecs_to_jiffies(500);
+ int i;
+
+ mutex_lock(&il->mutex);
+ D_MAC80211("enter\n");
+
+ if (il->txq == NULL)
+ goto out;
+
+ for (i = 0; i < il->hw_params.max_txq_num; i++) {
+ struct il_queue *q;
+
+ if (i == il->cmd_queue)
+ continue;
+
+ q = &il->txq[i].q;
+ if (q->read_ptr == q->write_ptr)
+ continue;
+
+ if (time_after(jiffies, timeout)) {
+ IL_ERR("Failed to flush queue %d\n", q->id);
+ break;
+ }
+
+ msleep(20);
+ }
+out:
+ D_MAC80211("leave\n");
+ mutex_unlock(&il->mutex);
+}
+EXPORT_SYMBOL(il_mac_flush);
+
/*
* On every watchdog tick we check (latest) time stamp. If it does not
* change during timeout period and queue is not empty we reset firmware.
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index a9a569f..37fe553 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1723,6 +1723,7 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum nl80211_iftype newtype, bool newp2p);
+void il_mac_flush(struct ieee80211_hw *hw, bool drop);
int il_alloc_txq_mem(struct il_priv *il);
void il_free_txq_mem(struct il_priv *il);
--
1.7.7.6

View File

@ -748,6 +748,10 @@ Patch21241: Input-add-support-for-Cypress-PS2-Trackpads.patch
# https://fedoraproject.org/wiki/Features/Checkpoint_Restore
Patch21242: criu-no-expert.patch
#rhbz 830151
Patch21243: mac80211-improve-latency-and-throughput-while-software.patch
Patch21244: iwlegacy-add-flush-callback.patch
# END OF PATCH DEFINITIONS
%endif
@ -1446,6 +1450,10 @@ ApplyPatch Input-add-support-for-Cypress-PS2-Trackpads.patch
# https://fedoraproject.org/wiki/Features/Checkpoint_Restore
ApplyPatch criu-no-expert.patch
#rhbz 830151
ApplyPatch mac80211-improve-latency-and-throughput-while-software.patch
ApplyPatch iwlegacy-add-flush-callback.patch
# END OF PATCH APPLICATIONS
%endif
@ -2304,6 +2312,7 @@ fi
* Fri Feb 01 2013 Josh Boyer <jwboyer@redhat.com>
- Linux v3.8-rc6
- Enable CONFIG_DMA_API_DEBUG
- Add patches to improve mac80211 latency and throughput (rhbz 830151)
* Thu Jan 31 2013 Josh Boyer <jwboyer@redhat.com> - 3.8.0-0.rc5.git3.1
- Linux v3.8-rc5-245-g04c2eee

View File

@ -0,0 +1,142 @@
From c790794fcb461842e6ae1d764b7f68e9a789d149 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Wed, 23 Jan 2013 12:32:45 +0100
Subject: [PATCH] mac80211: improve latency and throughput while software
scanning
Patch vastly improve latency while scanning. Slight throughput
improvements were observed as well. Is intended for improve performance
of voice and video applications, when scan is periodically requested by
user space (i.e. default NetworkManager behaviour).
Patch remove latency requirement based on PM_QOS_NETWORK_LATENCY,
this value is 2000 seconds by default (i.e. approximately 0.5 hour !?!).
Also remove listen interval requirement, which based on beaconing and
depending on BSS parameters. It can make we stay off-channel for a
second or more.
Instead try to offer the best latency that we could, i.e. be off-channel
no longer than PASSIVE channel scan time: 125 ms. That mean we will
scan two ACTIVE channels and go back to on-channel, and one PASSIVE
channel, and go back to on-channel.
Patch also decrease PASSIVE channel scan time to about 110 ms.
As drawback patch increase overall scan time. On my tests, when scanning
both 2GHz and 5GHz bands, scanning time increase from 5 seconds up to 10
seconds. Since that increase happen only when we are associated, I think
it can be acceptable. If eventually better scan time is needed for
situations when we lose signal and quickly need to decide to which AP
roam, additional scan flag or parameter can be introduced.
I tested patch by doing:
while true; do iw dev wlan0 scan; sleep 3; done > /dev/null
and
ping -i0.2 -c 1000 HOST
on remote and local machine, results are as below:
* Ping from local periodically scanning machine to AP:
Unpatched: rtt min/avg/max/mdev = 0.928/24.946/182.135/36.873 ms
Patched: rtt min/avg/max/mdev = 0.928/19.678/150.845/33.130 ms
* Ping from remote machine to periodically scanning machine:
Unpatched: rtt min/avg/max/mdev = 1.637/120.683/709.139/164.337 ms
Patched: rtt min/avg/max/mdev = 1.807/26.893/201.435/40.284 ms
Throughput measured by scp show following results.
* Upload to periodically scanning machine:
Unpatched: 3.9MB/s 03:15
Patched: 4.3MB/s 02:58
* Download from periodically scanning machine:
Unpatched: 5.5MB/s 02:17
Patched: 6.2MB/s 02:02
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/scan.c | 32 +++++---------------------------
1 file changed, 5 insertions(+), 27 deletions(-)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index bf82e69..e6b2ebc 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -27,7 +27,7 @@
#define IEEE80211_PROBE_DELAY (HZ / 33)
#define IEEE80211_CHANNEL_TIME (HZ / 33)
-#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 8)
+#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 9)
static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
{
@@ -547,8 +547,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
bool associated = false;
bool tx_empty = true;
bool bad_latency;
- bool listen_int_exceeded;
- unsigned long min_beacon_int = 0;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_channel *next_chan;
enum mac80211_scan_state next_scan_state;
@@ -567,11 +565,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
if (sdata->u.mgd.associated) {
associated = true;
- if (sdata->vif.bss_conf.beacon_int <
- min_beacon_int || min_beacon_int == 0)
- min_beacon_int =
- sdata->vif.bss_conf.beacon_int;
-
if (!qdisc_all_tx_empty(sdata->dev)) {
tx_empty = false;
break;
@@ -588,34 +581,19 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
* see if we can scan another channel without interfering
* with the current traffic situation.
*
- * Since we don't know if the AP has pending frames for us
- * we can only check for our tx queues and use the current
- * pm_qos requirements for rx. Hence, if no tx traffic occurs
- * at all we will scan as many channels in a row as the pm_qos
- * latency allows us to. Additionally we also check for the
- * currently negotiated listen interval to prevent losing
- * frames unnecessarily.
- *
- * Otherwise switch back to the operating channel.
+ * Keep good latency, do not stay off-channel more than 125 ms.
*/
bad_latency = time_after(jiffies +
- ieee80211_scan_get_channel_time(next_chan),
- local->leave_oper_channel_time +
- usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY)));
-
- listen_int_exceeded = time_after(jiffies +
- ieee80211_scan_get_channel_time(next_chan),
- local->leave_oper_channel_time +
- usecs_to_jiffies(min_beacon_int * 1024) *
- local->hw.conf.listen_interval);
+ ieee80211_scan_get_channel_time(next_chan),
+ local->leave_oper_channel_time + HZ / 8);
if (associated && !tx_empty) {
if (local->scan_req->flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
next_scan_state = SCAN_ABORT;
else
next_scan_state = SCAN_SUSPEND;
- } else if (associated && (bad_latency || listen_int_exceeded)) {
+ } else if (associated && bad_latency) {
next_scan_state = SCAN_SUSPEND;
} else {
next_scan_state = SCAN_SET_CHANNEL;
--
1.8.1