2d2dafcdb26a24773cccf600b1af7944167a2e3b
[openwrt.git] / target / linux / generic / patches-3.10 / 010-tsq_queueing_minimum.patch
1 From 98e09386c0ef4dfd48af7ba60ff908f0d525cdee Mon Sep 17 00:00:00 2001
2 From: Eric Dumazet <edumazet@google.com>
3 Date: Wed, 13 Nov 2013 14:32:54 +0000
4 Subject: tcp: tsq: restore minimal amount of queueing
5
6 After commit c9eeec26e32e ("tcp: TSQ can use a dynamic limit"), several
7 users reported throughput regressions, notably on mvneta and wifi
8 adapters.
9
10 802.11 AMPDU requires a fair amount of queueing to be effective.
11
12 This patch partially reverts the change done in tcp_write_xmit()
13 so that the minimal amount is sysctl_tcp_limit_output_bytes.
14
15 It also remove the use of this sysctl while building skb stored
16 in write queue, as TSO autosizing does the right thing anyway.
17
18 Users with well behaving NICS and correct qdisc (like sch_fq),
19 can then lower the default sysctl_tcp_limit_output_bytes value from
20 128KB to 8KB.
21
22 This new usage of sysctl_tcp_limit_output_bytes permits each driver
23 authors to check how their driver performs when/if the value is set
24 to a minimum of 4KB.
25
26 Normally, line rate for a single TCP flow should be possible,
27 but some drivers rely on timers to perform TX completion and
28 too long TX completion delays prevent reaching full throughput.
29
30 Fixes: c9eeec26e32e ("tcp: TSQ can use a dynamic limit")
31 Signed-off-by: Eric Dumazet <edumazet@google.com>
32 Reported-by: Sujith Manoharan <sujith@msujith.org>
33 Reported-by: Arnaud Ebalard <arno@natisbad.org>
34 Tested-by: Sujith Manoharan <sujith@msujith.org>
35 Cc: Felix Fietkau <nbd@openwrt.org>
36 Signed-off-by: David S. Miller <davem@davemloft.net>
37 ---
38 --- a/Documentation/networking/ip-sysctl.txt
39 +++ b/Documentation/networking/ip-sysctl.txt
40 @@ -571,9 +571,6 @@ tcp_limit_output_bytes - INTEGER
41         typical pfifo_fast qdiscs.
42         tcp_limit_output_bytes limits the number of bytes on qdisc
43         or device to reduce artificial RTT/cwnd and reduce bufferbloat.
44 -       Note: For GSO/TSO enabled flows, we try to have at least two
45 -       packets in flight. Reducing tcp_limit_output_bytes might also
46 -       reduce the size of individual GSO packet (64KB being the max)
47         Default: 131072
48  
49  tcp_challenge_ack_limit - INTEGER
50 --- a/net/ipv4/tcp.c
51 +++ b/net/ipv4/tcp.c
52 @@ -807,12 +807,6 @@ static unsigned int tcp_xmit_size_goal(s
53                 xmit_size_goal = min_t(u32, gso_size,
54                                        sk->sk_gso_max_size - 1 - hlen);
55  
56 -               /* TSQ : try to have at least two segments in flight
57 -                * (one in NIC TX ring, another in Qdisc)
58 -                */
59 -               xmit_size_goal = min_t(u32, xmit_size_goal,
60 -                                      sysctl_tcp_limit_output_bytes >> 1);
61 -
62                 xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
63  
64                 /* We try hard to avoid divides here */
65 --- a/net/ipv4/tcp_output.c
66 +++ b/net/ipv4/tcp_output.c
67 @@ -1866,8 +1866,12 @@ static bool tcp_write_xmit(struct sock *
68                  *  - better RTT estimation and ACK scheduling
69                  *  - faster recovery
70                  *  - high rates
71 +                * Alas, some drivers / subsystems require a fair amount
72 +                * of queued bytes to ensure line rate.
73 +                * One example is wifi aggregation (802.11 AMPDU)
74                  */
75 -               limit = max(skb->truesize, sk->sk_pacing_rate >> 10);
76 +               limit = max_t(unsigned int, sysctl_tcp_limit_output_bytes,
77 +                             sk->sk_pacing_rate >> 10);
78  
79                 if (atomic_read(&sk->sk_wmem_alloc) > limit) {
80                         set_bit(TSQ_THROTTLED, &tp->tsq_flags);