Hi,

this series ensures that rcv_wnd and window_clamp do not exceed the
maximum window size representable for the connection's window scale
factor.

This is most visible when TCP window scaling is not used for a
connection. In that case, the advertised window is limited to 65535
bytes, but rcv_wnd or window_clamp can still grow beyond 65535 when
large receive buffers are used. The resulting mismatch breaks
calculations that depend on the advertised window, such as the ACK
decision in __tcp_ack_snd_check(), and can prevent immediate ACKs.

Similar effects may also occur when window scaling is in use, e.g. if
the application dynamically adjusts SO_RCVBUF in unusual ways or when
the rmem sysctl parameters change during a connection’s lifetime.

Summary:

- Patch 1 keeps rcv_wnd capped by the (window scale-limited)
  window_clamp at connection start.
- Patch 3 and 6 ensure that window_clamp is limited to the
  representable window when it is updated.
- The other patches add packetdrill tests to verify the new behavior.

A simple iperf test on a virtme-ng VM (Intel i5-7500, 4 cores,
loopback) shows a noticeable improvement with window scaling disabled:

Fixed receive buffer:

- sysctl net.ipv4.tcp_window_scaling=0
- Server: iperf -l 256K -w 256K -s
- Client: iperf -l 256K -w 256K -c 127.0.0.1 -t 30
- net-next: ~47 Gbit/sec
- with this series: ~62 Gbit/sec

Receive buffer autotuning (net.ipv4.tcp_rmem = 4096 131072 7813888):

- sysctl net.ipv4.tcp_window_scaling=0
- Server: iperf -s
- Client: iperf -c 127.0.0.1 -t 30
- net-next: ~48 Gbit/sec
- with this series: ~60 Gbit/sec

Signed-off-by: Simon Baatz <[email protected]>
---
Simon Baatz (7):
      tcp: keep rcv_wnd/rcv_ssthresh clamped by window_clamp if no scaling in 
use
      selftests/net: packetdrill: verify non-scaled rcv_wnd initialization
      tcp: Ensure window_clamp is limited to representable window
      selftests/net: packetdrill: add tcp_rcv_wnd_snd_ack_no_scaling.pkt
      selftests/net: packetdrill: add TCP_WINDOW_CLAMP test
      tcp: use tcp_set_window_clamp() for SO_RCVLOWAT
      selftests/net: packetdrill: add test for SO_RCVLOWAT window clamp

 net/ipv4/tcp.c                                     |  6 +++-
 net/ipv4/tcp_input.c                               | 13 ++++++--
 net/ipv4/tcp_minisocks.c                           |  8 +++--
 net/ipv4/tcp_output.c                              |  5 +--
 .../net/packetdrill/tcp_rcv_sockopt_lowat.pkt      | 24 ++++++++++++++
 .../net/packetdrill/tcp_rcv_sockopt_wnd_clamp.pkt  | 28 ++++++++++++++++
 .../packetdrill/tcp_rcv_wnd_active_no_scaling.pkt  | 27 ++++++++++++++++
 .../tcp_rcv_wnd_active_peer_no_scaling.pkt         | 26 +++++++++++++++
 .../packetdrill/tcp_rcv_wnd_passive_no_scaling.pkt | 30 ++++++++++++++++++
 .../tcp_rcv_wnd_passive_peer_no_scaling.pkt        | 29 +++++++++++++++++
 .../packetdrill/tcp_rcv_wnd_snd_ack_no_scaling.pkt | 37 ++++++++++++++++++++++
 11 files changed, 225 insertions(+), 8 deletions(-)
---
base-commit: b3e69fc3196fc421e26196e7792f17b0463edc6f
change-id: 20260402-tcp_rcv_exact_clamp_and_wnd-427d853e7491

Best regards,
-- 
Simon Baatz <[email protected]>



Reply via email to