From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.bufferbloat.net (Postfix) with ESMTPS id 4A16B3CB35 for ; Sun, 24 Apr 2022 22:12:49 -0400 (EDT) Received: by mail-ed1-x52f.google.com with SMTP id d6so11672741ede.8 for ; Sun, 24 Apr 2022 19:12:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :content-transfer-encoding; bh=/DgnE4dYTtDynifFbJWFnVemvNpsazSEm829hnK7ESU=; b=eThdqg58qp+MH9zW1dT32lHgfWgjnV7+poCwp9ud6TYIjqGXaCy03cJpA7V+ND45Ff sM1OJEEEKefuoQIsaabPVzacsBss+MDiNJnrNeejF8ynm4tTzn5jThxHUvXusNmKrq7e DwZ/Vvm6nC+oYBLueLtpCjNBfnt+/uU+ZGNs3GCxWYubstrp1LB2xbICdPTr5JNc0pKX dokqaBa+6FTHdLU0FvqvDUNT8IYJqqx9yZaMkz5mQj5S0mb0q8pqu8K3n/0fgsCYpk3u syXSef2trKWFwCnMyhK8wqcYSp93OiHhiCgyMzWdYHL8AsoF4ytyR/Adi07C4n8Ly6w1 j84g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:content-transfer-encoding; bh=/DgnE4dYTtDynifFbJWFnVemvNpsazSEm829hnK7ESU=; b=1ZhppDgj6lGQDoj6TxSWArGs45G8vKrZJQVhYx3NFiCle4wRRzLej5hxsBYE0KtQXH UIOrycF12Qg9lWUDE+zcq9oftYVqe0Or/Vc337cw0NQZnLfE3yclOnAby/i5V+vkXFaE 5+v/XgW5TCy5t5lBv4jJR13iUgIFZF+KepStMl6o9BPY6TRfCt8zsKm4SYQ90MZCi5Zi oQtTXZlSWxJVMoKplcbuWRBSEVjLeQ+x6HInZkTzxsuCcaRLQPc3YEgHjdJo4V8OLJVm X+KrVbJYw0PSpDhZEFhOpdqVk1uDXe3DH8cec+ErdIAMf2rzzQcyluYmRK6Xb0kF9FfF XVMw== X-Gm-Message-State: AOAM531nW9FiGqpCh+wneCq0u7pjcfn2CU/P9Qa3HRy2trsfCyj0xEg6 /z2uoWuvLFuwY6Q2zp2bIXMHnEuucOTyXzeZ6y2ovxyt X-Google-Smtp-Source: ABdhPJzeJJ7OVaPFC0ocX+ZjE+yjznkK8HKeY/w9OvQ4iNNX+wc9LYSqYMPAtyOTc5ajQdb/dumnSmk/j5iNa5freEw= X-Received: by 2002:a05:6402:5ca:b0:423:f330:f574 with SMTP id n10-20020a05640205ca00b00423f330f574mr16991139edx.116.1650852767468; Sun, 24 Apr 2022 19:12:47 -0700 (PDT) MIME-Version: 1.0 References: <20220425003407.3002429-1-eric.dumazet@gmail.com> In-Reply-To: <20220425003407.3002429-1-eric.dumazet@gmail.com> From: Dave Taht Date: Sun, 24 Apr 2022 19:12:34 -0700 Message-ID: To: Rpm Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: [Rpm] Fwd: [PATCH net] tcp: fix potential xmit stalls caused by TCP_NOTSENT_LOWAT X-BeenThere: rpm@lists.bufferbloat.net X-Mailman-Version: 2.1.20 Precedence: list List-Id: revolutions per minute - a new metric for measuring responsiveness List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Apr 2022 02:12:49 -0000 ---------- Forwarded message --------- From: Eric Dumazet Date: Sun, Apr 24, 2022 at 7:00 PM Subject: [PATCH net] tcp: fix potential xmit stalls caused by TCP_NOTSENT_L= OWAT To: David S . Miller , Jakub Kicinski , Paolo Abeni Cc: netdev , Eric Dumazet , Eric Dumazet , Doug Porter , Soheil Hassas Yeganeh , Neal Cardwell From: Eric Dumazet I had this bug sitting for too long in my pile, it is time to fix it. Thanks to Doug Porter for reminding me of it! We had various attempts in the past, including commit 0cbe6a8f089e ("tcp: remove SOCK_QUEUE_SHRUNK"), but the issue is that TCP stack currently only generates EPOLLOUT from input path, when tp->snd_una has advanced and skb(s) cleaned from rtx queue. If a flow has a big RTT, and/or receives SACKs, it is possible that the notsent part (tp->write_seq - tp->snd_nxt) reaches 0 and no more data can be sent until tp->snd_una finally advances. What is needed is to also check if POLLOUT needs to be generated whenever tp->snd_nxt is advanced, from output path. This bug triggers more often after an idle period, as we do not receive ACK for at least one RTT. tcp_notsent_lowat could be a fraction of what CWND and pacing rate would allow to send during this RTT. In a followup patch, I will remove the bogus call to tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED) from tcp_check_space(). Fact that we have decided to generate an EPOLLOUT does not mean the application has immediately refilled the transmit queue. This optimistic call might have been the reason the bug seemed not too serious. Tested: 200 ms rtt, 1% packet loss, 32 MB tcp_rmem[2] and tcp_wmem[2] $ echo 500000 >/proc/sys/net/ipv4/tcp_notsent_lowat $ cat bench_rr.sh SUM=3D0 for i in {1..10} do V=3D`netperf -H remote_host -l30 -t TCP_RR -- -r 10000000,10000 -o LOCAL_BYTES_SENT | egrep -v "MIGRATED|Bytes"` echo $V SUM=3D$(($SUM + $V)) done echo SUM=3D$SUM Before patch: $ bench_rr.sh 130000000 80000000 140000000 140000000 140000000 140000000 130000000 40000000 90000000 110000000 SUM=3D1140000000 After patch: $ bench_rr.sh 430000000 590000000 530000000 450000000 450000000 350000000 450000000 490000000 480000000 460000000 SUM=3D4680000000 # This is 410 % of the value before patch. Fixes: c9bee3b7fdec ("tcp: TCP_NOTSENT_LOWAT socket option") Signed-off-by: Eric Dumazet Reported-by: Doug Porter Cc: Soheil Hassas Yeganeh Cc: Neal Cardwell --- include/net/tcp.h | 1 + net/ipv4/tcp_input.c | 12 +++++++++++- net/ipv4/tcp_output.c | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 9987b3fba9f202632916cc439af9d17f1e68bcd3..cc1295037533a7741e454f7c040= f77a21deae02b 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -621,6 +621,7 @@ void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req); void tcp_reset(struct sock *sk, struct sk_buff *skb); void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *= skb); void tcp_fin(struct sock *sk); +void tcp_check_space(struct sock *sk); /* tcp_timer.c */ void tcp_init_xmit_timers(struct sock *); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2088f93fa37b5fb9110e7933242a27bd4009990e..48f6075228600896daa6507c4cd= 06acfc851a0fa 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5454,7 +5454,17 @@ static void tcp_new_space(struct sock *sk) INDIRECT_CALL_1(sk->sk_write_space, sk_stream_write_space, sk); } -static void tcp_check_space(struct sock *sk) +/* Caller made space either from: + * 1) Freeing skbs in rtx queues (after tp->snd_una has advanced) + * 2) Sent skbs from output queue (and thus advancing tp->snd_nxt) + * + * We might be able to generate EPOLLOUT to the application if: + * 1) Space consumed in output/rtx queues is below sk->sk_sndbuf/2 + * 2) notsent amount (tp->write_seq - tp->snd_nxt) became + * small enough that tcp_stream_memory_free() decides it + * is time to generate EPOLLOUT. + */ +void tcp_check_space(struct sock *sk) { /* pairs with tcp_poll() */ smp_mb(); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9ede847f4199844c5884e3f62ea450562072a0a7..1ca2f28c9981018e6cfaee3435d= 711467af6048d 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -82,6 +82,7 @@ static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPORIGDATASENT, tcp_skb_pcount(skb)); + tcp_check_space(sk); } /* SND.NXT, if window was not shrunk or the amount of shrunk was less than= one -- 2.36.0.rc2.479.g8af0fa9b8e-goog --=20 I tried to build a better future, a few times: https://wayforward.archive.org/?site=3Dhttps%3A%2F%2Fwww.icei.org Dave T=C3=A4ht CEO, TekLibre, LLC