diff options
author | Felix Fietkau <nbd@openwrt.org> | 2013-11-14 22:01:24 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2013-11-14 22:01:24 +0000 |
commit | 2077361f128ff32dd6bb9fed7a4b3cd813863a9c (patch) | |
tree | 824e7cb1eec541c2e73620d09aceee4d7d61cd3b /target/linux | |
parent | 1f819564d117cd344fea583fc2f0bf6a622d0407 (diff) | |
download | upstream-2077361f128ff32dd6bb9fed7a4b3cd813863a9c.tar.gz upstream-2077361f128ff32dd6bb9fed7a4b3cd813863a9c.tar.bz2 upstream-2077361f128ff32dd6bb9fed7a4b3cd813863a9c.zip |
kernel: backport an upstream fix to improve TCP performance for wifi drivers
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 38810
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/generic/patches-3.10/010-tsq_queueing_minimum.patch | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.10/010-tsq_queueing_minimum.patch b/target/linux/generic/patches-3.10/010-tsq_queueing_minimum.patch new file mode 100644 index 0000000000..2d2dafcdb2 --- /dev/null +++ b/target/linux/generic/patches-3.10/010-tsq_queueing_minimum.patch @@ -0,0 +1,80 @@ +From 98e09386c0ef4dfd48af7ba60ff908f0d525cdee Mon Sep 17 00:00:00 2001 +From: Eric Dumazet <edumazet@google.com> +Date: Wed, 13 Nov 2013 14:32:54 +0000 +Subject: tcp: tsq: restore minimal amount of queueing + +After commit c9eeec26e32e ("tcp: TSQ can use a dynamic limit"), several +users reported throughput regressions, notably on mvneta and wifi +adapters. + +802.11 AMPDU requires a fair amount of queueing to be effective. + +This patch partially reverts the change done in tcp_write_xmit() +so that the minimal amount is sysctl_tcp_limit_output_bytes. + +It also remove the use of this sysctl while building skb stored +in write queue, as TSO autosizing does the right thing anyway. + +Users with well behaving NICS and correct qdisc (like sch_fq), +can then lower the default sysctl_tcp_limit_output_bytes value from +128KB to 8KB. + +This new usage of sysctl_tcp_limit_output_bytes permits each driver +authors to check how their driver performs when/if the value is set +to a minimum of 4KB. + +Normally, line rate for a single TCP flow should be possible, +but some drivers rely on timers to perform TX completion and +too long TX completion delays prevent reaching full throughput. + +Fixes: c9eeec26e32e ("tcp: TSQ can use a dynamic limit") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: Sujith Manoharan <sujith@msujith.org> +Reported-by: Arnaud Ebalard <arno@natisbad.org> +Tested-by: Sujith Manoharan <sujith@msujith.org> +Cc: Felix Fietkau <nbd@openwrt.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- +--- a/Documentation/networking/ip-sysctl.txt ++++ b/Documentation/networking/ip-sysctl.txt +@@ -571,9 +571,6 @@ tcp_limit_output_bytes - INTEGER + typical pfifo_fast qdiscs. + tcp_limit_output_bytes limits the number of bytes on qdisc + or device to reduce artificial RTT/cwnd and reduce bufferbloat. +- Note: For GSO/TSO enabled flows, we try to have at least two +- packets in flight. Reducing tcp_limit_output_bytes might also +- reduce the size of individual GSO packet (64KB being the max) + Default: 131072 + + tcp_challenge_ack_limit - INTEGER +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -807,12 +807,6 @@ static unsigned int tcp_xmit_size_goal(s + xmit_size_goal = min_t(u32, gso_size, + sk->sk_gso_max_size - 1 - hlen); + +- /* TSQ : try to have at least two segments in flight +- * (one in NIC TX ring, another in Qdisc) +- */ +- xmit_size_goal = min_t(u32, xmit_size_goal, +- sysctl_tcp_limit_output_bytes >> 1); +- + xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal); + + /* We try hard to avoid divides here */ +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1866,8 +1866,12 @@ static bool tcp_write_xmit(struct sock * + * - better RTT estimation and ACK scheduling + * - faster recovery + * - high rates ++ * Alas, some drivers / subsystems require a fair amount ++ * of queued bytes to ensure line rate. ++ * One example is wifi aggregation (802.11 AMPDU) + */ +- limit = max(skb->truesize, sk->sk_pacing_rate >> 10); ++ limit = max_t(unsigned int, sysctl_tcp_limit_output_bytes, ++ sk->sk_pacing_rate >> 10); + + if (atomic_read(&sk->sk_wmem_alloc) > limit) { + set_bit(TSQ_THROTTLED, &tp->tsq_flags); |