diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-11-14 22:01:24 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-11-14 22:01:24 +0000 |
commit | 22bff5f108d20b4d4b3d79fd37d14ece1b1ede03 (patch) | |
tree | 4b9300eb0c2018575309da3edac65e3f5c6773eb /target/linux/generic | |
parent | 6a5d9d3669407bd66fd514c67f5b5484be11877e (diff) |
kernel: backport an upstream fix to improve TCP performance for wifi drivers
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@38810 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic')
-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); |