| 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 | --- a/net/ipv4/tcp_input.c |
| 48 | +++ b/net/ipv4/tcp_input.c |
| 49 | @@ -231,7 +231,11 @@ static inline void TCP_ECN_check_ce(stru |
| 50 | tcp_enter_quickack_mode((struct sock *)tp); |
| 51 | break; |
| 52 | case INET_ECN_CE: |
| 53 | - tp->ecn_flags |= TCP_ECN_DEMAND_CWR; |
| 54 | + if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) { |
| 55 | + /* Better not delay acks, sender can have a very low cwnd */ |
| 56 | + tcp_enter_quickack_mode((struct sock *)tp); |
| 57 | + tp->ecn_flags |= TCP_ECN_DEMAND_CWR; |
| 58 | + } |
| 59 | /* fallinto */ |
| 60 | default: |
| 61 | tp->ecn_flags |= TCP_ECN_SEEN; |
| 62 | |