6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
[ Upstream commit 21b29e74ffe5a6c851c235bb80bf5ee26292c67b ]
Some applications (like selftests/net/tcp_mmap.c) call SO_RCVLOWAT on their listener, before accept().
This has an unfortunate effect on wscale selection in tcp_select_initial_window() during 3WHS.
For instance, tcp_mmap was negotiating wscale 4, regardless of tcp_rmem[2] and sysctl_rmem_max.
Do not change tp->window_clamp if it is zero or bigger than our computed value.
Zero value is special, it allows tcp_select_initial_window() to enable autotuning.
Note that SO_RCVLOWAT use on listener is probably not wise, because tp->scaling_ratio has a default value, possibly wrong.
Fixes: d1361840f8c5 ("tcp: fix SO_RCVLOWAT and RCVBUF autotuning") Signed-off-by: Eric Dumazet edumazet@google.com Reviewed-by: Kuniyuki Iwashima kuniyu@google.com Reviewed-by: Neal Cardwell ncardwell@google.com Link: https://patch.msgid.link/20251003184119.2526655-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 89040007c7b70..ba36f558f144c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1771,6 +1771,7 @@ EXPORT_IPV6_MOD(tcp_peek_len); /* Make sure sk_rcvbuf is big enough to satisfy SO_RCVLOWAT hint */ int tcp_set_rcvlowat(struct sock *sk, int val) { + struct tcp_sock *tp = tcp_sk(sk); int space, cap;
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) @@ -1789,7 +1790,9 @@ int tcp_set_rcvlowat(struct sock *sk, int val) space = tcp_space_from_win(sk, val); if (space > sk->sk_rcvbuf) { WRITE_ONCE(sk->sk_rcvbuf, space); - WRITE_ONCE(tcp_sk(sk)->window_clamp, val); + + if (tp->window_clamp && tp->window_clamp < val) + WRITE_ONCE(tp->window_clamp, val); } return 0; }