aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2019-01-16 18:05:34 -0500
committerDavid S. Miller <davem@davemloft.net>2019-01-17 18:12:26 -0500
commit590d2026d62418bb27de9ca87526e9131c1f48af (patch)
tree6d2de504c98a46b7dcefed405151b02957e896a0
parent9721e709fa68ef9b860c322b474cfbd1f8285b0f (diff)
tcp: retry more conservatively on local congestion
Previously when the sender fails to retransmit a data packet on timeout due to congestion in the local host (e.g. throttling in qdisc), it'll retry within an RTO up to 500ms. In low-RTT networks such as data-centers, RTO is often far below the default minimum 200ms (and the cap 500ms). Then local host congestion could trigger a retry storm pouring gas to the fire. Worse yet, the retry counter (icsk_retransmits) is not properly updated so the aggressive retry may exceed the system limit (15 rounds) until the packet finally slips through. On such rare events, it's wise to retry more conservatively (500ms) and update the stats properly to reflect these incidents and follow the system limit. Note that this is consistent with the behavior when a keep-alive probe is dropped due to local congestion. Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Neal Cardwell <ncardwell@google.com> Reviewed-by: Soheil Hassas Yeganeh <soheil@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/tcp_timer.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index c36089aa3515..d7399a89469d 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -500,14 +500,13 @@ void tcp_retransmit_timer(struct sock *sk)
500 500
501 tcp_enter_loss(sk); 501 tcp_enter_loss(sk);
502 502
503 icsk->icsk_retransmits++;
503 if (tcp_retransmit_skb(sk, tcp_rtx_queue_head(sk), 1) > 0) { 504 if (tcp_retransmit_skb(sk, tcp_rtx_queue_head(sk), 1) > 0) {
504 /* Retransmission failed because of local congestion, 505 /* Retransmission failed because of local congestion,
505 * do not backoff. 506 * Let senders fight for local resources conservatively.
506 */ 507 */
507 if (!icsk->icsk_retransmits)
508 icsk->icsk_retransmits = 1;
509 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 508 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
510 min(icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL), 509 TCP_RESOURCE_PROBE_INTERVAL,
511 TCP_RTO_MAX); 510 TCP_RTO_MAX);
512 goto out; 511 goto out;
513 } 512 }
@@ -528,7 +527,6 @@ void tcp_retransmit_timer(struct sock *sk)
528 * the 120 second clamps though! 527 * the 120 second clamps though!
529 */ 528 */
530 icsk->icsk_backoff++; 529 icsk->icsk_backoff++;
531 icsk->icsk_retransmits++;
532 530
533out_reset_timer: 531out_reset_timer:
534 /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is 532 /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is