]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
tcp: always seek for minimal rtt in tcp_rcv_rtt_update()
authorEric Dumazet <edumazet@google.com>
Tue, 13 May 2025 19:39:15 +0000 (19:39 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Jun 2025 10:04:18 +0000 (11:04 +0100)
[ Upstream commit b879dcb1aeeca278eacaac0b1e2425b1c7599f9f ]

tcp_rcv_rtt_update() goal is to maintain an estimation of the RTT
in tp->rcv_rtt_est.rtt_us, used by tcp_rcv_space_adjust()

When TCP TS are enabled, tcp_rcv_rtt_update() is using
EWMA to smooth the samples.

Change this to immediately latch the incoming value if it
is lower than tp->rcv_rtt_est.rtt_us, so that tcp_rcv_space_adjust()
does not overshoot tp->rcvq_space.space and sk->sk_rcvbuf.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250513193919.1089692-8-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/ipv4/tcp_input.c

index c874ed9484b54413cf119363a270bca2423786d2..ad91377f6cfaecb0512c530835704d6c1996c846 100644 (file)
@@ -640,10 +640,12 @@ EXPORT_SYMBOL(tcp_initialize_rcv_mss);
  */
 static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
 {
-       u32 new_sample = tp->rcv_rtt_est.rtt_us;
-       long m = sample;
+       u32 new_sample, old_sample = tp->rcv_rtt_est.rtt_us;
+       long m = sample << 3;
 
-       if (new_sample != 0) {
+       if (old_sample == 0 || m < old_sample) {
+               new_sample = m;
+       } else {
                /* If we sample in larger samples in the non-timestamp
                 * case, we could grossly overestimate the RTT especially
                 * with chatty applications or bulk transfer apps which
@@ -654,17 +656,9 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
                 * else with timestamps disabled convergence takes too
                 * long.
                 */
-               if (!win_dep) {
-                       m -= (new_sample >> 3);
-                       new_sample += m;
-               } else {
-                       m <<= 3;
-                       if (m < new_sample)
-                               new_sample = m;
-               }
-       } else {
-               /* No previous measure. */
-               new_sample = m << 3;
+               if (win_dep)
+                       return;
+               new_sample = old_sample - (old_sample >> 3) + sample;
        }
 
        tp->rcv_rtt_est.rtt_us = new_sample;