]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mptcp: fix receive space timestamp initialization
authorPaolo Abeni <pabeni@redhat.com>
Tue, 3 Feb 2026 18:41:18 +0000 (19:41 +0100)
committerJakub Kicinski <kuba@kernel.org>
Thu, 5 Feb 2026 02:45:09 +0000 (18:45 -0800)
MPTCP initialize the receive buffer stamp in mptcp_rcv_space_init(),
using the provided subflow stamp. Such helper is invoked in several
places; for passive sockets, space init happened at clone time.

In such scenario, MPTCP ends-up accesses the subflow stamp before
its initialization, leading to quite randomic timing for the first
receive buffer auto-tune event, as the timestamp for newly created
subflow is not refreshed there.

Fix the issue moving the stamp initialization out of the mentioned helper,
at the data transfer start, and always using a fresh timestamp.

Fixes: 013e3179dbd2 ("mptcp: fix rcv space initialization")
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260203-net-next-mptcp-misc-feat-6-20-v1-2-31ec8bfc56d1@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/mptcp/protocol.c
net/mptcp/protocol.h

index 758a6dcb1d7baaabba7f62ec09917348bacad05e..8d16ed00fcb4f613148e7867aee794e9747256cd 100644 (file)
@@ -2087,8 +2087,8 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied)
 
        msk->rcvq_space.copied += copied;
 
-       mstamp = div_u64(tcp_clock_ns(), NSEC_PER_USEC);
-       time = tcp_stamp_us_delta(mstamp, msk->rcvq_space.time);
+       mstamp = mptcp_stamp();
+       time = tcp_stamp_us_delta(mstamp, READ_ONCE(msk->rcvq_space.time));
 
        rtt_us = msk->rcvq_space.rtt_us;
        if (rtt_us && time < (rtt_us >> 3))
@@ -3548,6 +3548,7 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
        __mptcp_propagate_sndbuf(nsk, ssk);
 
        mptcp_rcv_space_init(msk, ssk);
+       msk->rcvq_space.time = mptcp_stamp();
 
        if (mp_opt->suboptions & OPTION_MPTCP_MPC_ACK)
                __mptcp_subflow_fully_established(msk, subflow, mp_opt);
@@ -3565,8 +3566,6 @@ void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk)
        msk->rcvq_space.copied = 0;
        msk->rcvq_space.rtt_us = 0;
 
-       msk->rcvq_space.time = tp->tcp_mstamp;
-
        /* initial rcv_space offering made to peer */
        msk->rcvq_space.space = min_t(u32, tp->rcv_wnd,
                                      TCP_INIT_CWND * tp->advmss);
@@ -3762,6 +3761,7 @@ void mptcp_finish_connect(struct sock *ssk)
         * accessing the field below
         */
        WRITE_ONCE(msk->local_key, subflow->local_key);
+       WRITE_ONCE(msk->rcvq_space.time, mptcp_stamp());
 
        mptcp_pm_new_connection(msk, ssk, 0);
 }
index 66e9735007912e565c8d565863edc938a17effb4..39afd44e072f2c04632e640fe2be818dd1db9640 100644 (file)
@@ -915,6 +915,11 @@ static inline bool mptcp_is_fully_established(struct sock *sk)
               READ_ONCE(mptcp_sk(sk)->fully_established);
 }
 
+static inline u64 mptcp_stamp(void)
+{
+       return div_u64(tcp_clock_ns(), NSEC_PER_USEC);
+}
+
 void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk);
 void mptcp_data_ready(struct sock *sk, struct sock *ssk);
 bool mptcp_finish_join(struct sock *sk);