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 commitmasterb025461303("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>
parent
0981f90e1a
commit
3a543ae0e2
|
|
@ -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)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue