From nobody Thu Nov 27 12:35:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D3A42FF170 for ; Wed, 12 Nov 2025 09:41:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940478; cv=none; b=cKBvTPk4Dn7povqB8tnRhSOSpFgmF7ONoR7Z6q4+IydTn+a8bsmqJ/JMYeF2RQNo3uMlixTd0EDiG4hUMaSviRza8dK/3EUooiQzOjh+D5xBE6QmJ4ecPqGjJIq7OM7ZjuF01LJ/ryTR1F/VxxQ2qjeMayP7ZdAUHMZvPY5Xekg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940478; c=relaxed/simple; bh=hWekfqISMwawK6ou/hsekClkoXSJFPaBKEf5ZNlDHCI=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=Deem/Kn8uydrPlfl3ijZW2onM2f+/OqDZyrD88BE+cNGCh690YSvpHVYVbQ+olyrIaEFXHwZtDxpGaA54UzKyceEbZxMP/qjPLgTNJoMXErXtQMTAxKETbVdQae1AYf8O8aqqlgvb0akBvdmRmq4TZ+TV8Akuo+0o6RNXn+hKi8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=PQvFB8GG; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PQvFB8GG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762940475; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nP0t32H+9s+S3v+S0jNJrHRkqU7yammwQNK7phn+5ho=; b=PQvFB8GGr/dIAodSTraQ17rOzojyt1L3ExFryA3VTZlV+efWUcQhX3380FAdUt8XJ9Y6vp EN7DxV3lHQvpr/NH0Fjj5hB08YP/cc7IrxmiwFEw9glIAqy/AiX/Yupxy+AWEFrsfqHIip XvfJ27GAsBPRX0bH5m4aOgkf4q2EisY= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-564-oQf1EOyfPgSE9AuPi-x2wA-1; Wed, 12 Nov 2025 04:41:14 -0500 X-MC-Unique: oQf1EOyfPgSE9AuPi-x2wA-1 X-Mimecast-MFC-AGG-ID: oQf1EOyfPgSE9AuPi-x2wA_1762940473 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5E7621801234 for ; Wed, 12 Nov 2025 09:41:13 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.44.33.120]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7F3D7196B8F7 for ; Wed, 12 Nov 2025 09:41:12 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH v4 mptcp-next 1/6] trace: mptcp: add mptcp_rcvbuf_grow tracepoint Date: Wed, 12 Nov 2025 10:41:01 +0100 Message-ID: <3446e68d2b4ea00475f82f3630a3b0a33a4b7b56.1762940290.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: W09LgBSkTc4Qtfb9dpGfdMD-JlWbXFsCgwNKGFIWhtg_1762940473 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" Similar to tcp, provide a new tracepoint to better understand mptcp_rcv_space_adjust() behavior, which presents many artifacts. Note that the used format string is so long that I preferred wrap it, contrary to guidance for quoted strings. Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- v2 -> v3: - use __entry->family; note that its value is show as raw number instead of string, as show_family_name is available only to net/core/ trace and I preferred not moving the mptcp traces there as we need mptcp-specific helpers, too. --- include/trace/events/mptcp.h | 77 ++++++++++++++++++++++++++++++++++++ net/mptcp/protocol.c | 3 ++ 2 files changed, 80 insertions(+) diff --git a/include/trace/events/mptcp.h b/include/trace/events/mptcp.h index 085b749cdd97..0f24ec65cea6 100644 --- a/include/trace/events/mptcp.h +++ b/include/trace/events/mptcp.h @@ -5,7 +5,13 @@ #if !defined(_TRACE_MPTCP_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_MPTCP_H =20 +#include +#include #include +#include +#include +#include +#include =20 #define show_mapping_status(status) \ __print_symbolic(status, \ @@ -178,6 +184,77 @@ TRACE_EVENT(subflow_check_data_avail, __entry->skb) ); =20 +#include + +TRACE_EVENT(mptcp_rcvbuf_grow, + + TP_PROTO(struct sock *sk, int time), + + TP_ARGS(sk, time), + + TP_STRUCT__entry( + __field(int, time) + __field(__u32, rtt_us) + __field(__u32, copied) + __field(__u32, inq) + __field(__u32, space) + __field(__u32, ooo_space) + __field(__u32, rcvbuf) + __field(__u32, rcv_wnd) + __field(__u8, scaling_ratio) + __field(__u16, sport) + __field(__u16, dport) + __field(__u16, family) + __array(__u8, saddr, 4) + __array(__u8, daddr, 4) + __array(__u8, saddr_v6, 16) + __array(__u8, daddr_v6, 16) + __field(const void *, skaddr) + ), + + TP_fast_assign( + struct mptcp_sock *msk =3D mptcp_sk(sk); + struct inet_sock *inet =3D inet_sk(sk); + __be32 *p32; + + __entry->time =3D time; + __entry->rtt_us =3D msk->rcvq_space.rtt_us >> 3; + __entry->copied =3D msk->rcvq_space.copied; + __entry->inq =3D mptcp_inq_hint(sk); + __entry->space =3D msk->rcvq_space.space; + __entry->ooo_space =3D RB_EMPTY_ROOT(&msk->out_of_order_queue) ? 0 : + MPTCP_SKB_CB(msk->ooo_last_skb)->end_seq - + msk->ack_seq; + + __entry->rcvbuf =3D sk->sk_rcvbuf; + __entry->rcv_wnd =3D atomic64_read(&msk->rcv_wnd_sent) - msk->ack_seq; + __entry->scaling_ratio =3D msk->scaling_ratio; + __entry->sport =3D ntohs(inet->inet_sport); + __entry->dport =3D ntohs(inet->inet_dport); + __entry->family =3D sk->sk_family; + + p32 =3D (__be32 *) __entry->saddr; + *p32 =3D inet->inet_saddr; + + p32 =3D (__be32 *) __entry->daddr; + *p32 =3D inet->inet_daddr; + + TP_STORE_ADDRS(__entry, inet->inet_saddr, inet->inet_daddr, + sk->sk_v6_rcv_saddr, sk->sk_v6_daddr); + + __entry->skaddr =3D sk; + ), + + TP_printk("time=3D%u rtt_us=3D%u copied=3D%u inq=3D%u space=3D%u ooo=3D%u= scaling_ratio=3D%u " + "rcvbuf=3D%u rcv_wnd=3D%u family=3D%d sport=3D%hu dport=3D%hu saddr=3D= %pI4 " + "daddr=3D%pI4 saddrv6=3D%pI6c daddrv6=3D%pI6c skaddr=3D%p", + __entry->time, __entry->rtt_us, __entry->copied, + __entry->inq, __entry->space, __entry->ooo_space, + __entry->scaling_ratio, __entry->rcvbuf, __entry->rcv_wnd, + __entry->family, __entry->sport, + __entry->dport, __entry->saddr, __entry->daddr, + __entry->saddr_v6, __entry->daddr_v6, __entry->skaddr) +); #endif /* _TRACE_MPTCP_H */ =20 /* This part must be outside protection */ diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index dce9f7a1b0eb..7510bc634585 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -28,6 +28,8 @@ #include "protocol.h" #include "mib.h" =20 +static unsigned int mptcp_inq_hint(const struct sock *sk); + #define CREATE_TRACE_POINTS #include =20 @@ -2103,6 +2105,7 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock = *msk, int copied) if (msk->rcvq_space.copied <=3D msk->rcvq_space.space) goto new_measure; =20 + trace_mptcp_rcvbuf_grow(sk, time); if (mptcp_rcvbuf_grow(sk, msk->rcvq_space.copied)) { /* Make subflows follow along. If we do not do this, we * get drops at subflow level if skbs can't be moved to --=20 2.51.1 From nobody Thu Nov 27 12:35:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2FF782DC76C for ; Wed, 12 Nov 2025 09:41:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940479; cv=none; b=FynAIsgWV4+UTnQ3Px8QPUxtDNOmCGIPXbpyqL6lrS+hgkvn7usa2thxhMdOGNLsmh7nbqC2nICjdoMdrqZbLIYYU8ahiltvLVB1HAYBdJs4qIsMPEsLpJyflZVPo85JnledbBN5XhqhSW6rweCHkGQZrHNc+KaJbQJjUBAQv5A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940479; c=relaxed/simple; bh=HXuSAo7CYUIfKUYDnCTsdRlarfpGPcJ+smgPvRxAZnc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=s7FDXQmlMsXggn8sPKnG+c6aEOIGFo/ySqP21bKw53uc2uQ+MOeuO/Lgri2YTSs0fTlUa8BTSwpDPDJzwwL1q2eQYNjHyLidJfQQAeOlf0u5ISEqy3gA4lRRB7BlW43BeVCP2y5kSJhr29Hhh4mxtnSB8fpERwUK2n1cgiR9gMA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=PVAh9hOj; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PVAh9hOj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762940477; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EtT43FHSJ9+POsdbG3U5BaTw6ZMDe4fvQQpT68Pr13o=; b=PVAh9hOjQzHJm46FfBaHovhsR26TSjb6LuD7fJj2SVd1MCI0XGd1/w2mmcUm9ST8j+/ar0 GVRmXdESmi5ZQ1lSEYnSfQp8WkVL7Ohl8oqy7EiALdwW5IH7Cb8dHOG0s0TaSd0GFBigDZ lNLLzztoRUor6Bg+AMLaFtcsIX0t25Y= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-217-RM_czQocOlGoLN3Vkxc-xg-1; Wed, 12 Nov 2025 04:41:15 -0500 X-MC-Unique: RM_czQocOlGoLN3Vkxc-xg-1 X-Mimecast-MFC-AGG-ID: RM_czQocOlGoLN3Vkxc-xg_1762940475 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0B23119560B2 for ; Wed, 12 Nov 2025 09:41:15 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.44.33.120]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 259B01955F1A for ; Wed, 12 Nov 2025 09:41:13 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH v4 mptcp-next 2/6] mptcp: fix receive space timestamp initialization. Date: Wed, 12 Nov 2025 10:41:02 +0100 Message-ID: <7152b5431a95b1b52251e7df3120590c28749a1a.1762940290.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 4o0RgYrTaw2tMiRSOtyhM8dHscXgu-vVdpV4GTUD2m8_1762940475 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" 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 of the mentioned helper, as soon at the data transfer start, and always using a fresh timestamp. This will also make the next patch cleaner. Fixes: 013e3179dbd2 ("mptcp: fix rcv space initialization") Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- v1 -> v2: -- factor out only the tstamp change for better reviewability --- net/mptcp/protocol.c | 7 ++++--- net/mptcp/protocol.h | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 7510bc634585..9bff316558b4 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2074,8 +2074,8 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock = *msk, int copied) =20 msk->rcvq_space.copied +=3D copied; =20 - mstamp =3D div_u64(tcp_clock_ns(), NSEC_PER_USEC); - time =3D tcp_stamp_us_delta(mstamp, msk->rcvq_space.time); + mstamp =3D mptcp_stamp(); + time =3D tcp_stamp_us_delta(mstamp, READ_ONCE(msk->rcvq_space.time)); =20 rtt_us =3D msk->rcvq_space.rtt_us; if (rtt_us && time < (rtt_us >> 3)) @@ -3508,7 +3508,7 @@ struct sock *mptcp_sk_clone_init(const struct sock *s= k, mptcp_copy_inaddrs(nsk, ssk); __mptcp_propagate_sndbuf(nsk, ssk); =20 - mptcp_rcv_space_init(msk, ssk); + msk->rcvq_space.time =3D mptcp_stamp(); =20 if (mp_opt->suboptions & OPTION_MPTCP_MPC_ACK) __mptcp_subflow_fully_established(msk, subflow, mp_opt); @@ -3723,6 +3723,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()); =20 mptcp_pm_new_connection(msk, ssk, 0); } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index f14eeb4fd884..49f211e427bf 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -913,6 +913,11 @@ static inline bool mptcp_is_fully_established(struct s= ock *sk) READ_ONCE(mptcp_sk(sk)->fully_established); } =20 +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); --=20 2.51.1 From nobody Thu Nov 27 12:35:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3A222FE589 for ; Wed, 12 Nov 2025 09:41:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940481; cv=none; b=ge7mQ355RWSQ/6ZJXmZ7WfFPEv77DNSNezQa/2YAJO+6t9jXyCv/i4ZnLxvjegjijU/XluEgadk9IvPcIhWD/qe9KN5DuaWnmQjoHne/95i5TcPkspMJfSu1rDs05lo7VfCLvzCMwBCFCutwHX+UYKdGRr3D+ReLJToPUI4q+Js= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940481; c=relaxed/simple; bh=PLh9ZvU1g6a8ooF1WHjSCJMpSFfhJMkfEtbSa7nsqRc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=LppP0oiVoARWBMubSEGviv8tCrMKEbeO4eYi1gYrXQQJVKkOe7gDjoI2gmRLt2WBdmHLP7quRowIlHk9gkAH68CLK/ZKWlz+x93Wpm6t9NKVW4KZPgukGEJ5UxJ1g6VyhR75JnAHjKkwAGeg2oXIpNrBT9kukYL/jOxFEeYz6/Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=cRooXtLB; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="cRooXtLB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762940478; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GIilrITen3j6h2UdykL6+krdKSEM+7zphzcJTBn/bso=; b=cRooXtLB+G/fUMfnsP0VU1+5f2A2WqiRi7x5V+zN2dFYWyFDRp2aXg9DtzEUZE0MF2ueWv dqX6SBcWPhsu2c5f9L+9b+fTWYI/4qekX2Fa60nd0IeYijZSGmI0MOgRop2OiNNr3qR/W2 5Du1x0kqApnGL43en/zWy5Alj+ieVDk= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-604-4u4Sd3ATPOaS_BmS42RCTw-1; Wed, 12 Nov 2025 04:41:17 -0500 X-MC-Unique: 4u4Sd3ATPOaS_BmS42RCTw-1 X-Mimecast-MFC-AGG-ID: 4u4Sd3ATPOaS_BmS42RCTw_1762940476 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9CB741956096 for ; Wed, 12 Nov 2025 09:41:16 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.44.33.120]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BAB9C196B8F7 for ; Wed, 12 Nov 2025 09:41:15 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH v4 mptcp-next 3/6] mptcp: consolidate rcv space init Date: Wed, 12 Nov 2025 10:41:03 +0100 Message-ID: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: vcuANEYRBh0MHT-BTHp2i1rng1oIWQWMDcoNT9Oj-DI_1762940476 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" MPTCP uses several calls of the mptcp_rcv_space_init() helper to initialize the receive space, with a catch-up call in mptcp_rcv_space_adjust(). Drop all the other strictly not needed invocations and move constant fields initialization at socket init/reset time. This removes a bit of complexity and will simplify the following patches. No functional changes intended. Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- v1 -> v2: - split helper consolidation out of v1 patch - additionally move 'copied' and 'rtt_us' initialization out of mptcp_rcv_space_init() --- net/mptcp/protocol.c | 34 +++++++++++++++++----------------- net/mptcp/protocol.h | 1 - net/mptcp/subflow.c | 2 -- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 9bff316558b4..06eabad05784 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2052,6 +2052,19 @@ static int __mptcp_recvmsg_mskq(struct sock *sk, str= uct msghdr *msg, return copied; } =20 +static void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock= *ssk) +{ + const struct tcp_sock *tp =3D tcp_sk(ssk); + + msk->rcvspace_init =3D 1; + + /* initial rcv_space offering made to peer */ + msk->rcvq_space.space =3D min_t(u32, tp->rcv_wnd, + TCP_INIT_CWND * tp->advmss); + if (msk->rcvq_space.space =3D=3D 0) + msk->rcvq_space.space =3D TCP_INIT_CWND * TCP_MSS_DEFAULT; +} + /* receive buffer autotuning. See tcp_rcv_space_adjust for more informati= on. * * Only difference: Use highest rtt estimate of the subflows in use. @@ -2938,6 +2951,8 @@ static void __mptcp_init_sock(struct sock *sk) msk->timer_ival =3D TCP_RTO_MIN; msk->scaling_ratio =3D TCP_DEFAULT_SCALING_RATIO; msk->backlog_len =3D 0; + msk->rcvq_space.copied =3D 0; + msk->rcvq_space.rtt_us =3D 0; =20 WRITE_ONCE(msk->first, NULL); inet_csk(sk)->icsk_sync_mss =3D mptcp_sync_mss; @@ -3381,6 +3396,8 @@ static int mptcp_disconnect(struct sock *sk, int flag= s) msk->bytes_sent =3D 0; msk->bytes_retrans =3D 0; msk->rcvspace_init =3D 0; + msk->rcvq_space.copied =3D 0; + msk->rcvq_space.rtt_us =3D 0; =20 /* for fallback's sake */ WRITE_ONCE(msk->ack_seq, 0); @@ -3518,23 +3535,6 @@ struct sock *mptcp_sk_clone_init(const struct sock *= sk, return nsk; } =20 -void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk) -{ - const struct tcp_sock *tp =3D tcp_sk(ssk); - - msk->rcvspace_init =3D 1; - msk->rcvq_space.copied =3D 0; - msk->rcvq_space.rtt_us =3D 0; - - msk->rcvq_space.time =3D tp->tcp_mstamp; - - /* initial rcv_space offering made to peer */ - msk->rcvq_space.space =3D min_t(u32, tp->rcv_wnd, - TCP_INIT_CWND * tp->advmss); - if (msk->rcvq_space.space =3D=3D 0) - msk->rcvq_space.space =3D TCP_INIT_CWND * TCP_MSS_DEFAULT; -} - static void mptcp_destroy(struct sock *sk) { struct mptcp_sock *msk =3D mptcp_sk(sk); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 49f211e427bf..7c9e143c0fb5 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -918,7 +918,6 @@ static inline u64 mptcp_stamp(void) return div_u64(tcp_clock_ns(), NSEC_PER_USEC); } =20 -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); bool mptcp_schedule_work(struct sock *sk); diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 294645e88684..32f06510ba7a 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -462,8 +462,6 @@ void __mptcp_sync_state(struct sock *sk, int state) =20 subflow =3D mptcp_subflow_ctx(ssk); __mptcp_propagate_sndbuf(sk, ssk); - if (!msk->rcvspace_init) - mptcp_rcv_space_init(msk, ssk); =20 if (sk->sk_state =3D=3D TCP_SYN_SENT) { /* subflow->idsn is always available is TCP_SYN_SENT state, --=20 2.51.1 From nobody Thu Nov 27 12:35:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D78252FF16E for ; Wed, 12 Nov 2025 09:41:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940482; cv=none; b=oqJU+rvx5DmAUekr6dcVwXc350pEabdmHN2Ta9YACALHqYbnRgW9lZ9+bS08RtSDtkllnXXgWcFa9VGSXdg9acd0K9mi1z50tVhcjcEgdnzcm9B3g+tQWfhJ9Qgo53byD/0PCgeikLolTEeYuHI8zdETW/OZU8UPV5V3iiRUhwU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940482; c=relaxed/simple; bh=ym7a5sdeBjRvKyysOwKQyvI738oppfOs/jBDz0nlIb4=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=ifxemfmWM7SrEo7bhAFuovxDWrDqSzxTkqTB82qEYsu6760Uv+NSFhEjEausNRDCu2x44N6JvauDU+CC5uyxF6Sd83G3G3WI+JyDa1a2H38bh0TKZBmV8WGAqsravA75++RsSN3m7oYcggEY/C7hFHloMDdpKeNCCbhM36l2L2A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=PtWAn4gE; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PtWAn4gE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762940480; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xr42XIT6/5lStrzXw0r+GES57H0Cw3EyXYZeOq2nNmo=; b=PtWAn4gEcqnJLluHnWcwmvBmi4oR/SdOUgyQdwWFeKlxLJqcrqMN2t2tpEc/5rgmxHchlY Pb7zElLrpzBMzXzS7qb44WzZV2CsekwQZtTScROf3R/Tgx/ARtGc8PU2BxQo5jzncJwWIN NPZKZ1vXEo5Pav9AgriZZMHmqT4VQl4= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-41-OB987pOhM0apiLxesixJxg-1; Wed, 12 Nov 2025 04:41:18 -0500 X-MC-Unique: OB987pOhM0apiLxesixJxg-1 X-Mimecast-MFC-AGG-ID: OB987pOhM0apiLxesixJxg_1762940478 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0C867195605B for ; Wed, 12 Nov 2025 09:41:18 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.44.33.120]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2D3CD1955F1A for ; Wed, 12 Nov 2025 09:41:16 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH v4 mptcp-next 4/6] mptcp: better rcv space initialization Date: Wed, 12 Nov 2025 10:41:04 +0100 Message-ID: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 7mcpadJMiCo9X-YE_OrtWmc8mmwyvZN3RHBFQ51Abds_1762940478 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" Each additional subflow can overshot the rcv space by a full rcv wnd, as the TCP socket at creation time will announce such window even if the MPTCP-level window is closed. Underestimating the initial real rcv space can overshot the initial rcv win increase significantly. Keep track explicitly of the rcv space contribution by newly created subflow, updating rcvq_space.space accordingly for every successfully completed subflow handshake. Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- net/mptcp/protocol.c | 44 ++++++++++++++++++++++++++++++-------------- net/mptcp/protocol.h | 30 ++++++++++++++++++++++++++++++ net/mptcp/subflow.c | 3 +++ 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 06eabad05784..4f23809e5369 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -925,6 +925,7 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk,= struct sock *ssk) mptcp_sockopt_sync_locked(msk, ssk); mptcp_stop_tout_timer(sk); __mptcp_propagate_sndbuf(sk, ssk); + __mptcp_propagate_rcvspace(sk, ssk); return true; } =20 @@ -2052,17 +2053,21 @@ static int __mptcp_recvmsg_mskq(struct sock *sk, st= ruct msghdr *msg, return copied; } =20 -static void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock= *ssk) +static void mptcp_rcv_space_init(struct mptcp_sock *msk) { - const struct tcp_sock *tp =3D tcp_sk(ssk); + struct sock *sk =3D (struct sock *)msk; =20 msk->rcvspace_init =3D 1; =20 - /* initial rcv_space offering made to peer */ - msk->rcvq_space.space =3D min_t(u32, tp->rcv_wnd, - TCP_INIT_CWND * tp->advmss); - if (msk->rcvq_space.space =3D=3D 0) + mptcp_data_lock(sk); + __mptcp_sync_rcvspace(sk); + + /* Paranoid check: at least one subflow pushed data to the msk. */ + if (msk->rcvq_space.space =3D=3D 0) { + DEBUG_NET_WARN_ON_ONCE(1); msk->rcvq_space.space =3D TCP_INIT_CWND * TCP_MSS_DEFAULT; + } + mptcp_data_unlock(sk); } =20 /* receive buffer autotuning. See tcp_rcv_space_adjust for more informati= on. @@ -2083,7 +2088,7 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock = *msk, int copied) return; =20 if (!msk->rcvspace_init) - mptcp_rcv_space_init(msk, msk->first); + mptcp_rcv_space_init(msk); =20 msk->rcvq_space.copied +=3D copied; =20 @@ -3524,6 +3529,7 @@ struct sock *mptcp_sk_clone_init(const struct sock *s= k, */ mptcp_copy_inaddrs(nsk, ssk); __mptcp_propagate_sndbuf(nsk, ssk); + __mptcp_propagate_rcvspace(nsk, ssk); =20 msk->rcvq_space.time =3D mptcp_stamp(); =20 @@ -3623,8 +3629,10 @@ static void mptcp_release_cb(struct sock *sk) __mptcp_sync_state(sk, msk->pending_state); if (__test_and_clear_bit(MPTCP_ERROR_REPORT, &msk->cb_flags)) __mptcp_error_report(sk); - if (__test_and_clear_bit(MPTCP_SYNC_SNDBUF, &msk->cb_flags)) + if (__test_and_clear_bit(MPTCP_SYNC_SNDBUF, &msk->cb_flags)) { __mptcp_sync_sndbuf(sk); + __mptcp_sync_rcvspace(sk); + } } } =20 @@ -3740,13 +3748,13 @@ bool mptcp_finish_join(struct sock *ssk) { struct mptcp_subflow_context *subflow =3D mptcp_subflow_ctx(ssk); struct mptcp_sock *msk =3D mptcp_sk(subflow->conn); - struct sock *parent =3D (void *)msk; + struct sock *sk =3D (void *)msk; bool ret =3D true; =20 pr_debug("msk=3D%p, subflow=3D%p\n", msk, subflow); =20 /* mptcp socket already closing? */ - if (!mptcp_is_fully_established(parent)) { + if (!mptcp_is_fully_established(sk)) { subflow->reset_reason =3D MPTCP_RST_EMPTCP; return false; } @@ -3760,7 +3768,15 @@ bool mptcp_finish_join(struct sock *ssk) } mptcp_subflow_joined(msk, ssk); spin_unlock_bh(&msk->fallback_lock); - mptcp_propagate_sndbuf(parent, ssk); + mptcp_data_lock(sk); + if (!sock_owned_by_user(sk)) { + __mptcp_propagate_sndbuf(sk, ssk); + __mptcp_propagate_rcvspace(sk, ssk); + } else { + __mptcp_bl_rcvspace(sk, ssk); + __set_bit(MPTCP_SYNC_SNDBUF, &mptcp_sk(sk)->cb_flags); + } + mptcp_data_unlock(sk); return true; } =20 @@ -3772,8 +3788,8 @@ bool mptcp_finish_join(struct sock *ssk) /* If we can't acquire msk socket lock here, let the release callback * handle it */ - mptcp_data_lock(parent); - if (!sock_owned_by_user(parent)) { + mptcp_data_lock(sk); + if (!sock_owned_by_user(sk)) { ret =3D __mptcp_finish_join(msk, ssk); if (ret) { sock_hold(ssk); @@ -3784,7 +3800,7 @@ bool mptcp_finish_join(struct sock *ssk) list_add_tail(&subflow->node, &msk->join_list); __set_bit(MPTCP_FLUSH_JOIN_LIST, &msk->cb_flags); } - mptcp_data_unlock(parent); + mptcp_data_unlock(sk); =20 if (!ret) { err_prohibited: diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 7c9e143c0fb5..adc0851bad69 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -360,6 +360,7 @@ struct mptcp_sock { =20 struct list_head backlog_list; /* protected by the data lock */ u32 backlog_len; + u32 bl_space; /* rcvspace propagation via bl */ }; =20 #define mptcp_data_lock(sk) spin_lock_bh(&(sk)->sk_lock.slock) @@ -976,6 +977,35 @@ static inline void mptcp_write_space(struct sock *sk) sk_stream_write_space(sk); } =20 +static inline void __mptcp_sync_rcvspace(struct sock *sk) +{ + struct mptcp_sock *msk =3D mptcp_sk(sk); + + msk->rcvq_space.space +=3D msk->bl_space; + msk->bl_space =3D 0; +} + +static inline u32 mptcp_subflow_rcvspace(struct sock *ssk) +{ + struct tcp_sock *tp =3D tcp_sk(ssk); + int space; + + space =3D min_t(u32, tp->rcv_wnd, TCP_INIT_CWND * tp->advmss); + if (space =3D=3D 0) + space =3D TCP_INIT_CWND * TCP_MSS_DEFAULT; + return space; +} + +static inline void __mptcp_propagate_rcvspace(struct sock *sk, struct sock= *ssk) +{ + mptcp_sk(sk)->rcvq_space.space +=3D mptcp_subflow_rcvspace(ssk); +} + +static inline void __mptcp_bl_rcvspace(struct sock *sk, struct sock *ssk) +{ + mptcp_sk(sk)->bl_space +=3D mptcp_subflow_rcvspace(ssk); +} + static inline void __mptcp_sync_sndbuf(struct sock *sk) { struct mptcp_subflow_context *subflow; diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 32f06510ba7a..1984fc609b82 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -462,6 +462,7 @@ void __mptcp_sync_state(struct sock *sk, int state) =20 subflow =3D mptcp_subflow_ctx(ssk); __mptcp_propagate_sndbuf(sk, ssk); + __mptcp_sync_rcvspace(sk); =20 if (sk->sk_state =3D=3D TCP_SYN_SENT) { /* subflow->idsn is always available is TCP_SYN_SENT state, @@ -516,8 +517,10 @@ static void mptcp_propagate_state(struct sock *sk, str= uct sock *ssk, =20 if (!sock_owned_by_user(sk)) { __mptcp_sync_state(sk, ssk->sk_state); + __mptcp_propagate_rcvspace(sk, ssk); } else { msk->pending_state =3D ssk->sk_state; + __mptcp_bl_rcvspace(sk, ssk); __set_bit(MPTCP_SYNC_STATE, &msk->cb_flags); } mptcp_data_unlock(sk); --=20 2.51.1 From nobody Thu Nov 27 12:35:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E04022FF16E for ; Wed, 12 Nov 2025 09:41:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940484; cv=none; b=u6/jz99STozN88nfzyU1BRFkYz0r8oUZXuscIXpbteaUwlxX9zyH8Djdl5fzREB8Fw2Rg6aA1VWsfXLaxChfstUcbEoBO47yHPdITz4/ee0KOltU8U0IzKGz5boLopB249wvRDbvGXHaYRQRwUjw0r1hdUGAPGgJtxOYwnUZFbk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940484; c=relaxed/simple; bh=6wHmFVicKh4RYIUHNeCSmg62dcdYN1wzB2dIzt1paww=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=QfQ+vArNTHOKOpivtWT4qFwuEudK9bpuWJeISCZepqwwopm6sciWh694nTMrljDdW7AehlrvGQROP+J5qdtxZ5IUgvhqHg4iXVN8kyUrIbwwBWBcKT2qqMkpOrFiUd23Y1rLXzLL/CAMB0Me++KOpJhWzcpl5xsWAhfrdVX+OyI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=eodrUiDR; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="eodrUiDR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762940481; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MAMgJuVbyT4nSXP0Rj3LoE5LfoQQ+XMZWipY+uPKB7U=; b=eodrUiDR8V4qSGreV3flPdm/wS+zg8Sdh2K0otTM3eV31E02LSohwZKhOCTqu5sIypzjcI IswJc/C7ZORb4k3CoJKfYnqNLSDz8ziONdsy6QZc9p6RepQhF6zXwIUgxtPTaaCZEuvZoR mheRQA013e1owUJHNqegBa2UUvFMCa4= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-283-dn-L39wWNwaoWKXlVO832Q-1; Wed, 12 Nov 2025 04:41:20 -0500 X-MC-Unique: dn-L39wWNwaoWKXlVO832Q-1 X-Mimecast-MFC-AGG-ID: dn-L39wWNwaoWKXlVO832Q_1762940479 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6F6E5195605B for ; Wed, 12 Nov 2025 09:41:19 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.44.33.120]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8F0491955F1A for ; Wed, 12 Nov 2025 09:41:18 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH v4 mptcp-next 5/6] mptcp: better mptcp-level RTT estimator Date: Wed, 12 Nov 2025 10:41:05 +0100 Message-ID: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: -pqCp5_pAKGQvfNyfDsQjFcAiJ2INUu0ROLE8_qzxX4_1762940479 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" The current MPTCP-level RTT estimator has several issues. On high speed links, the MPTCP-level receive buffer auto-tuning happens with a frequency well above the TCP-level's one. That in turn can cause excessive/unneeded receive buffer increase. On such links, the initial rtt_us value is considerably higher than the actual delay, and the current mptcp_rcv_space_adjust() updates msk->rcvq_space.rtt_us with a period equal to the such field previous value. If the initial rtt_us is 40ms, its first update will happen after 40ms, even if the subflows see actual RTT orders of magnitude lower. Additionally, setting the msk rtt to the maximum among all the subflows RTTs makes DRS constantly overshooting the rcvbuf size when a subflow has considerable higher latency than the other(s). Finally, during unidirectional bulk transfers with multiple active subflows, the TCP-level RTT estimator occasionally sees considerably higher value than the real link delay, i.e. when the packet scheduler reacts to an incoming ack on given subflow pushing data on a different subflow. Address the issue with a more accurate RTT estimation strategy: the MPTCP-level RTT is set to the minimum of all the subflows, in a rcv-win based interval, feeding data into the MPTCP-receive buffer. Use some care to avoid updating msk and ssk level fields too often and to avoid 'too high' samples. Fixes: a6b118febbab ("mptcp: add receive buffer auto-tuning") Signed-off-by: Paolo Abeni --- v3 -> v4: - really refresh msk rtt after a full win per subflow (off-by-one in prev revision) - sync mptcp_rcv_space_adjust() comment with the new code v1 -> v2: - do not use explicit reset flags - do rcv win based decision instead - discard 0 rtt_us samples from subflows - discard samples on non empty rx queue - discard "too high" samples, see the code comments WRT the whys --- include/trace/events/mptcp.h | 2 +- net/mptcp/protocol.c | 77 ++++++++++++++++++++++-------------- net/mptcp/protocol.h | 7 +++- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/include/trace/events/mptcp.h b/include/trace/events/mptcp.h index 0f24ec65cea6..d30d2a6a8b42 100644 --- a/include/trace/events/mptcp.h +++ b/include/trace/events/mptcp.h @@ -218,7 +218,7 @@ TRACE_EVENT(mptcp_rcvbuf_grow, __be32 *p32; =20 __entry->time =3D time; - __entry->rtt_us =3D msk->rcvq_space.rtt_us >> 3; + __entry->rtt_us =3D msk->rcv_rtt_est.rtt_us >> 3; __entry->copied =3D msk->rcvq_space.copied; __entry->inq =3D mptcp_inq_hint(sk); __entry->space =3D msk->rcvq_space.space; diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 4f23809e5369..9a0a4bfa25e6 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -870,6 +870,42 @@ static bool move_skbs_to_msk(struct mptcp_sock *msk, s= truct sock *ssk) return moved; } =20 +static void mptcp_rcv_rtt_update(struct mptcp_sock *msk, + struct mptcp_subflow_context *subflow) +{ + const struct tcp_sock *tp =3D tcp_sk(subflow->tcp_sock); + u32 rtt_us =3D tp->rcv_rtt_est.rtt_us; + u8 sr =3D tp->scaling_ratio; + + /* MPTCP can react to incoming acks pushing data on different subflows, + * causing apparent high RTT: ignore large samples; also do the update + * only on RTT changes + */ + if (tp->rcv_rtt_est.seq =3D=3D subflow->prev_rtt_seq || + (subflow->prev_rtt_us && (rtt_us >> 1) > subflow->prev_rtt_us)) + return; + + /* Similar to plain TCP, only consider samples with empty RX queue. */ + if (!rtt_us || mptcp_data_avail(msk)) + return; + + /* Refresh the RTT after a full win per subflow */ + subflow->prev_rtt_us =3D rtt_us; + subflow->prev_rtt_seq =3D tp->rcv_rtt_est.seq; + if (after(subflow->map_seq, msk->rcv_rtt_est.seq)) { + msk->rcv_rtt_est.seq =3D subflow->map_seq + tp->rcv_wnd * + (msk->pm.extra_subflows + 1); + msk->rcv_rtt_est.rtt_us =3D rtt_us; + msk->scaling_ratio =3D sr; + return; + } + + if (rtt_us < msk->rcv_rtt_est.rtt_us) + msk->rcv_rtt_est.rtt_us =3D rtt_us; + if (sr < msk->scaling_ratio) + msk->scaling_ratio =3D sr; +} + void mptcp_data_ready(struct sock *sk, struct sock *ssk) { struct mptcp_subflow_context *subflow =3D mptcp_subflow_ctx(ssk); @@ -883,6 +919,7 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk) return; =20 mptcp_data_lock(sk); + mptcp_rcv_rtt_update(msk, subflow); if (!sock_owned_by_user(sk)) { /* Wake-up the reader only for in-sequence data */ if (move_skbs_to_msk(msk, ssk) && mptcp_epollin_ready(sk)) @@ -2060,6 +2097,7 @@ static void mptcp_rcv_space_init(struct mptcp_sock *m= sk) msk->rcvspace_init =3D 1; =20 mptcp_data_lock(sk); + msk->rcv_rtt_est.seq =3D atomic64_read(&msk->rcv_wnd_sent); __mptcp_sync_rcvspace(sk); =20 /* Paranoid check: at least one subflow pushed data to the msk. */ @@ -2072,15 +2110,15 @@ static void mptcp_rcv_space_init(struct mptcp_sock = *msk) =20 /* receive buffer autotuning. See tcp_rcv_space_adjust for more informati= on. * - * Only difference: Use highest rtt estimate of the subflows in use. + * Only difference: use lowest rtt estimate of the subflows in use, see + * mptcp_rcv_rtt_update(). */ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied) { struct mptcp_subflow_context *subflow; struct sock *sk =3D (struct sock *)msk; - u8 scaling_ratio =3D U8_MAX; - u32 time, advmss =3D 1; - u64 rtt_us, mstamp; + u32 rtt_us, time; + u64 mstamp; =20 msk_owned_by_me(msk); =20 @@ -2095,29 +2133,8 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock= *msk, int copied) mstamp =3D mptcp_stamp(); time =3D tcp_stamp_us_delta(mstamp, READ_ONCE(msk->rcvq_space.time)); =20 - rtt_us =3D msk->rcvq_space.rtt_us; - if (rtt_us && time < (rtt_us >> 3)) - return; - - rtt_us =3D 0; - mptcp_for_each_subflow(msk, subflow) { - const struct tcp_sock *tp; - u64 sf_rtt_us; - u32 sf_advmss; - - tp =3D tcp_sk(mptcp_subflow_tcp_sock(subflow)); - - sf_rtt_us =3D READ_ONCE(tp->rcv_rtt_est.rtt_us); - sf_advmss =3D READ_ONCE(tp->advmss); - - rtt_us =3D max(sf_rtt_us, rtt_us); - advmss =3D max(sf_advmss, advmss); - scaling_ratio =3D min(tp->scaling_ratio, scaling_ratio); - } - - msk->rcvq_space.rtt_us =3D rtt_us; - msk->scaling_ratio =3D scaling_ratio; - if (time < (rtt_us >> 3) || rtt_us =3D=3D 0) + rtt_us =3D READ_ONCE(msk->rcv_rtt_est.rtt_us); + if (rtt_us =3D=3D U32_MAX || time < (rtt_us >> 3)) return; =20 if (msk->rcvq_space.copied <=3D msk->rcvq_space.space) @@ -2957,7 +2974,8 @@ static void __mptcp_init_sock(struct sock *sk) msk->scaling_ratio =3D TCP_DEFAULT_SCALING_RATIO; msk->backlog_len =3D 0; msk->rcvq_space.copied =3D 0; - msk->rcvq_space.rtt_us =3D 0; + msk->rcv_rtt_est.rtt_us =3D U32_MAX; + msk->scaling_ratio =3D U8_MAX; =20 WRITE_ONCE(msk->first, NULL); inet_csk(sk)->icsk_sync_mss =3D mptcp_sync_mss; @@ -3402,7 +3420,8 @@ static int mptcp_disconnect(struct sock *sk, int flag= s) msk->bytes_retrans =3D 0; msk->rcvspace_init =3D 0; msk->rcvq_space.copied =3D 0; - msk->rcvq_space.rtt_us =3D 0; + msk->scaling_ratio =3D U8_MAX; + msk->rcv_rtt_est.rtt_us =3D U32_MAX; =20 /* for fallback's sake */ WRITE_ONCE(msk->ack_seq, 0); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index adc0851bad69..051f21b06d33 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -340,11 +340,14 @@ struct mptcp_sock { */ struct mptcp_pm_data pm; struct mptcp_sched_ops *sched; + struct { + u32 rtt_us; /* Minimum RTT of subflows */ + u64 seq; /* Refresh RTT after this seq */ + } rcv_rtt_est; struct { int space; /* bytes copied in last measurement window */ int copied; /* bytes copied in this measurement window */ u64 time; /* start time of measurement window */ - u64 rtt_us; /* last maximum rtt of subflows */ } rcvq_space; u8 scaling_ratio; bool allow_subflows; @@ -523,6 +526,8 @@ struct mptcp_subflow_context { u32 map_data_len; __wsum map_data_csum; u32 map_csum_len; + u32 prev_rtt_us; + u32 prev_rtt_seq; u32 request_mptcp : 1, /* send MP_CAPABLE */ request_join : 1, /* send MP_JOIN */ request_bkup : 1, --=20 2.51.1 From nobody Thu Nov 27 12:35:27 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C58182FD7D8 for ; Wed, 12 Nov 2025 09:41:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940485; cv=none; b=HM9uzBuhYnMPDxCXgBGjmEHhiOaNGPAgMfbE4sSP9WREbGHI0teUylmv7VP2skWC6Pz3vEUHGzw8xcahYcb+/XPZPZPy6VBwFtUA7dCBJnVRpt7IRxUbSez1JEJCudqeuc6qyE6lgfMdXqFeY9uKK8H1xzn5y7XxiQO6pBlCFII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762940485; c=relaxed/simple; bh=7RS+fImQz2wXeS0IGgWHrzBUAqWJ3kjuFW3bZ0MHXV4=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=liiPuuPpsdrBdtdRQlJLqEY6tujMa23rbOo8z64bxPkW/1Eti5OuLhhzyk6C7BisKZLs7sbU8acqKVjE1A54cwPukK4MjR1dnqEJNLaOunOpLg1ylW6KWzGK2xO2QjEmCytgP4FroJlNnVlBlLpa3aNW4WuG4wMgEJ7j+mpGYRQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=N/4NRr/w; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="N/4NRr/w" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762940483; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NL9+tDaUTNARL7xn5nRZGTuAkpmCvJqa1blRxIrXs8g=; b=N/4NRr/w/iZTNuFKpE/Cyld18HPEtIvO6WUrrSLv5E9NNFDkOukDL3OVswYgSxPg096Ytb PijG5Bh9vjcg5bckOGmUnGU2yxKdXjh0P95DGnjtFzT1g6Zr5fBM+3+eFsFB5mfEuXGDfG 9gN0/KJCQFFnItkNHwi5pEnP/1rN2jc= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-257-CiWU_n6lO-yRoYVuuvkMPA-1; Wed, 12 Nov 2025 04:41:21 -0500 X-MC-Unique: CiWU_n6lO-yRoYVuuvkMPA-1 X-Mimecast-MFC-AGG-ID: CiWU_n6lO-yRoYVuuvkMPA_1762940480 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D16F9180034D for ; Wed, 12 Nov 2025 09:41:20 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.44.33.120]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F16251955F1A for ; Wed, 12 Nov 2025 09:41:19 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Subject: [PATCH v4 mptcp-next 6/6] mptcp: add receive queue awareness in tcp_rcv_space_adjust() Date: Wed, 12 Nov 2025 10:41:06 +0100 Message-ID: In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: ZmisBhQz80OtEalBL7xHFflUL-ZOnrbT-aCUgdNwgRc_1762940480 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" This is the mptcp counter-part of commit ea33537d8292 ("tcp: add receive queue awareness in tcp_rcv_space_adjust()"). Prior to this commit: ESTAB 33165568 0 192.168.255.2:5201 192.168.255.1:53380 \ skmem:(r33076416,rb33554432,t0,tb91136,f448,w0,o0,bl0,d0) After: ESTAB 3279168 0 192.168.255.2:5201 192.168.255.1]:53042 \ skmem:(r3190912,rb3719956,t0,tb91136,f1536,w0,o0,bl0,d0) (same tput) Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau --- net/mptcp/protocol.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 9a0a4bfa25e6..a9dbdb413c7e 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2137,11 +2137,13 @@ static void mptcp_rcv_space_adjust(struct mptcp_soc= k *msk, int copied) if (rtt_us =3D=3D U32_MAX || time < (rtt_us >> 3)) return; =20 - if (msk->rcvq_space.copied <=3D msk->rcvq_space.space) + copied =3D msk->rcvq_space.copied; + copied -=3D mptcp_inq_hint(sk); + if (copied <=3D msk->rcvq_space.space) goto new_measure; =20 trace_mptcp_rcvbuf_grow(sk, time); - if (mptcp_rcvbuf_grow(sk, msk->rcvq_space.copied)) { + if (mptcp_rcvbuf_grow(sk, copied)) { /* Make subflows follow along. If we do not do this, we * get drops at subflow level if skbs can't be moved to * the mptcp rx queue fast enough (announced rcv_win can @@ -2155,7 +2157,7 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock = *msk, int copied) slow =3D lock_sock_fast(ssk); /* subflows can be added before tcp_init_transfer() */ if (tcp_sk(ssk)->rcvq_space.space) - tcp_rcvbuf_grow(ssk, msk->rcvq_space.copied); + tcp_rcvbuf_grow(ssk, copied); unlock_sock_fast(ssk, slow); } } --=20 2.51.1