mptcp: update window_clamp on subflows when SO_RCVBUF is set

Add __mptcp_subflow_set_rcvbuf() helper to write the subflow sk_rcvbuf,
but also to call the recently added tcp_set_rcvbuf() helper to update
window_clamp. This is needed because the window clap is updated when
scaling_ratio changes, in tcp_measure_rcv_mss(). Until scaling_ratio
changes, the subflow is stuck with the old window clamp which may be
based on a small initial buffer.

Use this new helper in both mptcp_sol_socket_sync_intval() (setsockopt
path) and sync_socket_options() (new subflow creation path).

Note that this patch depends on commit b025461303 ("tcp: update
window_clamp when SO_RCVBUF is set"): it fixes the issue on TCP side,
but the same fix is needed on MPTCP side as well.

Fixes: a2cbb16039 ("tcp: Update window clamping condition")
Cc: stable@vger.kernel.org
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/619
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-5-701e96419f2f@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
master
Gang Yan 2026-05-15 06:27:36 +02:00 committed by Paolo Abeni
parent 0981f90e1a
commit 3a543ae0e2
1 changed files with 8 additions and 2 deletions

View File

@ -67,6 +67,12 @@ static int mptcp_get_int_option(struct mptcp_sock *msk, sockptr_t optval,
return 0; return 0;
} }
static void __mptcp_subflow_set_rcvbuf(struct sock *ssk, int val)
{
WRITE_ONCE(ssk->sk_rcvbuf, val);
tcp_set_rcvbuf(ssk, val);
}
static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, int val) static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, int val)
{ {
struct mptcp_subflow_context *subflow; struct mptcp_subflow_context *subflow;
@ -100,7 +106,7 @@ static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, in
case SO_RCVBUF: case SO_RCVBUF:
case SO_RCVBUFFORCE: case SO_RCVBUFFORCE:
ssk->sk_userlocks |= SOCK_RCVBUF_LOCK; ssk->sk_userlocks |= SOCK_RCVBUF_LOCK;
WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); __mptcp_subflow_set_rcvbuf(ssk, sk->sk_rcvbuf);
break; break;
case SO_MARK: case SO_MARK:
if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) { if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) {
@ -1560,7 +1566,7 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
mptcp_subflow_ctx(ssk)->cached_sndbuf = sk->sk_sndbuf; mptcp_subflow_ctx(ssk)->cached_sndbuf = sk->sk_sndbuf;
} }
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) if (sk->sk_userlocks & SOCK_RCVBUF_LOCK)
WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); __mptcp_subflow_set_rcvbuf(ssk, sk->sk_rcvbuf);
} }
if (sock_flag(sk, SOCK_LINGER)) { if (sock_flag(sk, SOCK_LINGER)) {