kernel: dont delay acks after ECN CE
[openwrt.git] / target / linux / generic / patches-3.3 / 060-tcp-ecn-dont-delay-ACKS-after-CE.patch
1 From patchwork Mon Aug  6 21:04:43 2012
2 Content-Type: text/plain; charset="utf-8"
3 MIME-Version: 1.0
4 Content-Transfer-Encoding: 7bit
5 Subject: [net-next] tcp: ecn: dont delay ACKS after CE
6 Date: Mon, 06 Aug 2012 11:04:43 -0000
7 From: Eric Dumazet <eric.dumazet@gmail.com>
8 X-Patchwork-Id: 175453
9 Message-Id: <1344287083.26674.83.camel@edumazet-glaptop>
10 To: David Miller <davem@davemloft.net>
11 Cc: netdev <netdev@vger.kernel.org>,
12         Neal Cardwell <ncardwell@google.com>
13
14 From: Eric Dumazet <edumazet@google.com>
15
16 While playing with CoDel and ECN marking, I discovered a
17 non optimal behavior of receiver of CE (Congestion Encountered)
18 segments.
19
20 In pathological cases, sender has reduced its cwnd to low values,
21 and receiver delays its ACK (by 40 ms).
22
23 While RFC 3168 6.1.3 (The TCP Receiver) doesn't explicitly recommend
24 to send immediate ACKS, we believe its better to not delay ACKS, because
25 a CE segment should give same signal than a dropped segment, and its
26 quite important to reduce RTT to give ECE/CWR signals as fast as
27 possible.
28
29 Note we already call tcp_enter_quickack_mode() from TCP_ECN_check_ce()
30 if we receive a retransmit, for the same reason.
31
32 Signed-off-by: Eric Dumazet <edumazet@google.com>
33 Cc: Neal Cardwell <ncardwell@google.com>
34 Acked-by: Neal Cardwell <ncardwell@google.com>
35
36 ---
37 net/ipv4/tcp_input.c |    6 +++++-
38  1 file changed, 5 insertions(+), 1 deletion(-)
39
40
41
42 --
43 To unsubscribe from this list: send the line "unsubscribe netdev" in
44 the body of a message to majordomo@vger.kernel.org
45 More majordomo info at  http://vger.kernel.org/majordomo-info.html
46
47 diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
48 index 2fd2bc9..fa2c2c2 100644
49 --- a/net/ipv4/tcp_input.c
50 +++ b/net/ipv4/tcp_input.c
51 @@ -237,7 +237,11 @@ static inline void TCP_ECN_check_ce(struct tcp_sock *tp, const struct sk_buff *s
52                         tcp_enter_quickack_mode((struct sock *)tp);
53                 break;
54         case INET_ECN_CE:
55 -               tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
56 +               if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) {
57 +                       /* Better not delay acks, sender can have a very low cwnd */
58 +                       tcp_enter_quickack_mode((struct sock *)tp);
59 +                       tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
60 +               }
61                 /* fallinto */
62         default:
63                 tp->ecn_flags |= TCP_ECN_SEEN;