]> git.ipfire.org Git - thirdparty/kernel/linux.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)
committerJakub Kicinski <kuba@kernel.org>
Thu, 15 May 2025 18:30:08 +0000 (11:30 -0700)
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>
net/ipv4/tcp_input.c

index 32b8b332c7d82e8c6a0716b26f2e048d68667864..4723d696492517143a2f3c035bfda6b05198a824 100644 (file)
@@ -664,10 +664,12 @@ EXPORT_IPV6_MOD(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
@@ -678,17 +680,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;