From nobody Thu Nov 5 07:36:18 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=165.173.182.52 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1793186146; b=UNWnC6azr8GuWPW/rbgP6DABuQAjeCa8tfCZAR/DJiwtmKKa3klZ1L+0oT5XaiD60OSq qCaB63JRZdje1MbjrmS/vcvnuICh1QcU92jqltf9wbD54NBTw/qqAo1HWANN0ewR+O8tG xX+tcPIj45LiPSqzOtXMDgIVOiOA8vW1qvqwLjFu8CES4bJDr4lImc8ijurWMBmTm74iQ Xcn3eTBBYo+jtaNZ01NhfFh/NjYEfz9na8xh5qM69qLwb+es9fPLSc1H3zo/w9nJeDgX/ OFWsqZNjhgcvVGW97fwoQf//+WaB5PiJ0+jmub83NAJffVC3tx5xkmsp+evMhs4Z/XQ== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793186146; h=DMARC-Filter:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Content-Transfer-Encoding:Message-Id:References: In-Reply-To:To:Cc:X-Mailer:X-ZohoMailClient; bh=/2BOEtMOXrwTmi7Wsdl4Aw/+k7fI2nZPAkr436p6KHk=; b=sBaggFpH4aTDhe3WCaFlAGHa78ZnZHLeArUvBEW+Zm+lOomsYt/JBaDUgnYCJFEuzgrp FCpZAb3qo6bizM29hhzgwc9mPZuPryKgjAJIdAdWLL7V+cqo1DF2k3wDzeqgQleAbq5r9 jhZFE4jiUn5dBC7lWyYuJMqayZ9i2zviTN7GPj8DuGiGRZI/83ALxWVT8O7eVqkvTrKOc CyvcImqnWKfvQRGTvOSViqgsflYPNUTTXdIynl2vr4wE6xthOMzuOf3GUUzg1Km9qONu8 apogckBeHZ0T0Wj0KxNwCg4+bP/YshMaKenbqwHrlQsyymLeAcXZS+hK61rRqZySk0g== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass header.from=mpiricsoftware.com; spf=pass smtp.mailfrom=mpiricsoftware.com; arc=pass header.oldest-pass=0 smtp.remote-ip=165.173.182.52 Received: from sender5-of-o52.zoho.com (sender5-of-o52.zoho.com [165.173.182.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7810B606A320 for ; Wed, 28 Oct 2026 11:15:46 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 7810B606A320 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mpiricsoftware.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mpiricsoftware.com ARC-Seal: i=1; a=rsa-sha256; t=1793186136; cv=none; d=zohomail.com; s=zohoarc; b=NtvRUn0mJLdxrWK6kX7r0wtgHTynY+pDXc9y2+eCI94XT/uTQ+MGonIu7qnMFJjFszxZjjzCpnszRg3ZufmhJ+WqDnqtLBW/K4DTOhcH+3d8O38uDqIHK8KWjS6DUNZpbWb+ftTAEHGXa5EjvZ1jvZZjqPvg1fUDfU77L2AwIC0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1793186136; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=/2BOEtMOXrwTmi7Wsdl4Aw/+k7fI2nZPAkr436p6KHk=; b=lC2GJVr3UzTvSTzdZc+DrZtIpOEijmtTuy31FN7WBiJDZR8DrLM56bw8mtLOyOD25bUJggfrHmtMNa0qL8Da1yOHaLyvhl1uAInrPT+EhtyUz2VwBTP3sb1OgDgAKnUymnu6YNpcMZqjh/BO3coXwq320ut3aggN8pUGCt/maS8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=mpiricsoftware.com; spf=pass smtp.mailfrom=shardul.b@mpiricsoftware.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1793186136; s=mpiric; d=mpiricsoftware.com; i=shardul.b@mpiricsoftware.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=/2BOEtMOXrwTmi7Wsdl4Aw/+k7fI2nZPAkr436p6KHk=; b=iBue9sC0yYpRyCfhh20dFdf0nn5Pxe1Cf4co1LjvhLYE9Iqq9qOKG32X/DYGIOzO a7chDkeJGyzoNYhyOj875C8RBF7eoFHpKPvZez+5x8WlzGhXExHKIScT3wB+OTU9znJ WVH8pj+lViPHM+oE/0eoeE8yjzGopVhY7efCXbik= Received: by smtp.zohomail.com with SMTPS id 1793186135023614.268806724573; Wed, 28 Oct 2026 04:15:35 -0700 (PDT) From: Shardul Bankar Date: Wed, 28 Oct 2026 16:45:08 +0530 Subject: [PATCH mptcp-next v5 1/4] mptcp: sched: avoid truncating the pacing rate in the scheduler X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20261028-mptcp_penalise_send_v2-v5-1-32fb379ce117@mpiricsoftware.com> References: <20261028-mptcp_penalise_send_v2-v5-0-32fb379ce117@mpiricsoftware.com> In-Reply-To: <20261028-mptcp_penalise_send_v2-v5-0-32fb379ce117@mpiricsoftware.com> To: mptcp@lists.linux.dev Cc: "Matthieu Baerts (NGI0)" , Janak Patel , Kalpan Jani , Shardul Bankar , Shardul Bankar , Abdul Wasey X-Mailer: b4 0.15.2 X-ZohoMailClient: External mptcp_subflow_get_send() derives each subflow's linger time and a running pacing-rate average through a u32 "pace", while sk_pacing_rate and avg_pacing_rate are unsigned long. The u32 truncates pacing rates above 4 GB/s, skewing subflow selection on fast paths. The running average has a second problem that widening "pace" does not address: it forms two rate * bytes products before dividing, and only the avg_pacing_rate term carries a (u64) cast. On 32-bit systems the uncast sk_pacing_rate * burst wraps at ordinary pacing rates. On 64-bit that product is safe, but avg_pacing_rate * wmem still wraps when a high pacing rate meets a send queue near the 2GB ceiling sk_wmem_queued allows. Either way a wrapped term can report the fastest subflow as the slowest. Widen "pace" to unsigned long, divide the linger time with a 64-bit divisor, and compute each product of the average in a 128-bit intermediate with mul_u64_u64_div_u64(), which bounds the error at one unit per term. Dividing each term before multiplying would avoid the wrap more cheaply, but that quotient truncates to zero once the queue holds a second or more of data, which is exactly the bufferbloated subflow this estimate needs to describe. Fixes: d5f49190def6 ("mptcp: allow picking different xmit subflows") Fixes: 3ce0852c86b9 ("mptcp: enforce HoL-blocking estimation") Suggested-by: Matthieu Baerts (NGI0) Signed-off-by: Shardul Bankar Tested-by: Abdul Wasey --- net/mptcp/protocol.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 02a4f479d9d8..886f00ee2a4d 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1633,7 +1633,8 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock= *msk) struct subflow_send_info send_info[SSK_MODE_MAX]; struct mptcp_subflow_context *subflow; struct sock *sk =3D (struct sock *)msk; - u32 pace, burst, wmem; + unsigned long pace; + u32 burst, wmem; int i, nr_active =3D 0; struct sock *ssk; u64 linger_time; @@ -1664,7 +1665,7 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock= *msk) continue; } =20 - linger_time =3D div_u64((u64)READ_ONCE(ssk->sk_wmem_queued) << 32, pace); + linger_time =3D div64_u64((u64)READ_ONCE(ssk->sk_wmem_queued) << 32, pac= e); if (linger_time < send_info[backup].linger_time) { send_info[backup].ssk =3D ssk; send_info[backup].linger_time =3D linger_time; @@ -1697,9 +1698,12 @@ struct sock *mptcp_subflow_get_send(struct mptcp_soc= k *msk) return ssk; =20 subflow =3D mptcp_subflow_ctx(ssk); - subflow->avg_pacing_rate =3D div_u64((u64)subflow->avg_pacing_rate * wmem= + - READ_ONCE(ssk->sk_pacing_rate) * burst, - burst + wmem); + /* 64-bit arithmetic overflows at high rate with a large queue */ + subflow->avg_pacing_rate =3D + mul_u64_u64_div_u64(subflow->avg_pacing_rate, wmem, + burst + wmem) + + mul_u64_u64_div_u64(READ_ONCE(ssk->sk_pacing_rate), burst, + burst + wmem); msk->snd_burst =3D burst; return ssk; } --=20 2.34.1 From nobody Thu Nov 5 07:36:18 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=165.173.182.52 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1793186154; b=QsMjXg4l6cFod111LLRGt43Vc+wE0g51zuwajuikA4QbmapC5u9WNUBw0s5/9LfdsCQF LUMl7axx+zgOJcXYdBFkPnRTXFe6n9mcHAMatLmRgKkXQv0pLVGHgSNfuZXQMr6bZZTJK s0gRGVyDICWGgGJrwtC3um8fqKYm5a+yst0D8gf4T1Zb2r9lxT6vyTdCwdrfWx+fYOl5C UqOQ0URYZhaJsUBt966oCcgJ5cvj0K9AdTJfz4xuHqn4Pza+CETI6MRseIT8QDOR81x8/ 5f6l516fiC27LSyMIcuwBg4F6Jc3T0acpNRfAjjSO8yJhYkQU8r/3TNc4WZ34BrjIFA== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793186154; h=DMARC-Filter:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Content-Transfer-Encoding:Message-Id:References: In-Reply-To:To:Cc:X-Mailer:X-ZohoMailClient; bh=q21RE6MccZGJhg5Lj2l+M+ogxP3l8KGSy8WYkdeSmp8=; b=2uTeLoLoqVyry8yKBkoBZYOjNk70tfU4BvST0U+xVgB8SGYuVCuVv03iW5RVON3PTtUm czo7lispzZkZJRdkqGepiHHZ9gwCngiBUW8ZOCytuus2s6NiwvFehFkRMB/RCsPKqI/FR VSqh0qv6M6YDJQknfPp1BuYIB2uhEW3klngedv5BAQvLbzMmSG7s2TwaRQ51COHS2dBAk ArzFfDfWfmmraIxQhnUNaEcDcgrUKNeu949d+OCtXaTvbX66gb4NHsxY/bGpIetOuAmem /TcKMrCZ9XI5Q1lwkEI17RJT4KNZ1ipiKRhAfE+HM9EcGxRoGhhDTqBiVnbAtCcFyxQ== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass header.from=mpiricsoftware.com; spf=pass smtp.mailfrom=mpiricsoftware.com; arc=pass header.oldest-pass=0 smtp.remote-ip=165.173.182.52 Received: from sender5-of-o52.zoho.com (sender5-of-o52.zoho.com [165.173.182.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D700B606A31C for ; Wed, 28 Oct 2026 11:15:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org D700B606A31C Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mpiricsoftware.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mpiricsoftware.com ARC-Seal: i=1; a=rsa-sha256; t=1793186140; cv=none; d=zohomail.com; s=zohoarc; b=a9gP9xvEAExXpGcujhF1YCQCYwOHpwdkKi72hn8DMGLLR95DM6waOTA+/YRwRqbfRxs5syFuZH19Q5nD3SwCkkXZ8pc9Tq7DLJGtsyAuDzmguNVx8KCcBED6oO8w7TqSdyJnkdih6ERXMvnbpJ+hBaDFt/gPyPsgomKvhJA7+Lo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1793186140; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=q21RE6MccZGJhg5Lj2l+M+ogxP3l8KGSy8WYkdeSmp8=; b=cIq1KKNrkz/+0+bsy3oQ0A8mRXKU1d39vK66HVgLFujY2TO8hJoHS/diyacGZ5DjCUZfH8por7c81R5DUvNt9j1E9ZFohaUzh9TpUcOg88LkrjiFj9mbE/fKWU9MMoLBzcnNYwZNqeWhP8h8ihMbz0QlBUgcTPhyuYBiug5pri4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=mpiricsoftware.com; spf=pass smtp.mailfrom=shardul.b@mpiricsoftware.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1793186140; s=mpiric; d=mpiricsoftware.com; i=shardul.b@mpiricsoftware.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=q21RE6MccZGJhg5Lj2l+M+ogxP3l8KGSy8WYkdeSmp8=; b=pgEZT/W7u9kBY7+wnAb6j1siV5RJzSvqUXQcAm4TTkv9tSgIemnrlGhUJvHJ2ZoY OEWU5pPuAJ2cTcDF74e9FVrCuLr3fAcUC+wxftCW8dmRBRJwfOu05eNiqqkWRsBD9x7 nICJLTvhD/BL9/JoaZvvWxosEBJAuqEvvyktEuac= Received: by smtp.zohomail.com with SMTPS id 1793186138188530.9443410752061; Wed, 28 Oct 2026 04:15:38 -0700 (PDT) From: Shardul Bankar Date: Wed, 28 Oct 2026 16:45:09 +0530 Subject: [PATCH mptcp-next v5 2/4] mptcp: sched: penalise a slow subflow by halving its cwnd X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20261028-mptcp_penalise_send_v2-v5-2-32fb379ce117@mpiricsoftware.com> References: <20261028-mptcp_penalise_send_v2-v5-0-32fb379ce117@mpiricsoftware.com> In-Reply-To: <20261028-mptcp_penalise_send_v2-v5-0-32fb379ce117@mpiricsoftware.com> To: mptcp@lists.linux.dev Cc: "Matthieu Baerts (NGI0)" , Janak Patel , Kalpan Jani , Shardul Bankar , Shardul Bankar , Abdul Wasey X-Mailer: b4 0.15.2 X-ZohoMailClient: External A poorly-performing but usable subflow (high latency, loss, bufferbloat) can soak up connection resources and cause head-of-line blocking of the aggregate stream. Give the default packet scheduler a way to send less than such a subflow's full congestion window. Once a subflow has been picked for transmission, flag it for penalisation when: - its smoothed pacing rate (avg_pacing_rate) is below half that of the fastest non-backup path, keying on rate, not RTT, so a slow-but-high-throughput path is left alone; - the fastest path is cwnd-limited (saturated), so shifting load off the slow path is worthwhile; - the subflow is in TCP_CA_Open, so its cwnd is not already being reduced by loss recovery; - its cwnd is still above MPTCP_PENALISE_MIN_CWND, so a subflow already at the floor is left to recover instead of being churned by a halving that can no longer reduce it; - it has not been penalised in the last RTT. Backup subflows do not take part in the fastest-path comparison. While an active subflow exists a backup carries no data, so both its rate estimate and its cwnd-limited state go stale; using one as the reference would penalise the subflow that is actually sending. The reduction halves tcp_snd_cwnd, floored at MPTCP_PENALISE_MIN_CWND, and halves ssthresh when cwnd is at or above it, following the out-of-tree mptcp.org implementation's ssthresh handling. The congestion control is left to raise the window again; this adds no MPTCP-side probe or timer. Split the conditions by the lock that covers them. The scheduler runs under the msk lock and only marks a candidate, using the rate comparison against the fastest subflow. The conditions belonging to the subflow itself (the cwnd floor, the CA_Open state and the once-per-RTT limiter) are evaluated where the penalty is applied, under that subflow's own socket lock, so the limiter's timestamp is written and read under one lock. The rate comparison reads the fastest subflow's state without holding its lock: that is a different socket from the one being pushed, and taking a second subflow's socket lock in the send path is not acceptable. The field is a bitfield, so READ_ONCE() does not apply; annotate it with data_race(). Halving the window without telling the congestion control is deliberately a simple first step: not every congestion control reacts to an external change the same way, and some may undo it quickly. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/345 Link: https://github.com/multipath-tcp/mptcp/blob/825b62d597b5/net/mptcp/mp= tcp_sched.c#L300-L330 Co-developed-by: Matthieu Baerts (NGI0) Signed-off-by: Shardul Bankar Tested-by: Abdul Wasey --- net/mptcp/protocol.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++= +--- net/mptcp/protocol.h | 2 ++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 886f00ee2a4d..395f9582ece8 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1624,6 +1624,45 @@ bool mptcp_subflow_active(struct mptcp_subflow_conte= xt *subflow) #define SSK_MODE_BACKUP 1 #define SSK_MODE_MAX 2 =20 +/* Penalise a subflow pacing below the fastest path's rate / this ratio */ +#define MPTCP_PENALISE_RATE_RATIO 2 +/* cwnd floor for the penalty: skip a subflow already there, and never red= uce + * below it (halving at the floor only churns congestion control). + */ +#define MPTCP_PENALISE_MIN_CWND 2 + +/* Rate-limit the penalty to at most once per subflow RTT, so the congesti= on + * control can grow the window back between reductions. + */ +static bool mptcp_penalise_throttle_ok(struct mptcp_subflow_context *subfl= ow) +{ + struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); + u32 rtt =3D usecs_to_jiffies(READ_ONCE(tcp_sk(ssk)->srtt_us) >> 3); + + return tcp_jiffies32 - subflow->last_penalise >=3D max_t(u32, rtt, 1); +} + +/* Halve cwnd, and ssthresh when cwnd is at or above it, under the subflow + * socket lock: the scheduler only marks a candidate, the conditions on th= is + * subflow are evaluated here, on current state. + */ +static void mptcp_penalise_cwnd(struct sock *ssk) +{ + struct mptcp_subflow_context *subflow =3D mptcp_subflow_ctx(ssk); + struct tcp_sock *tp =3D tcp_sk(ssk); + u32 cwnd =3D tcp_snd_cwnd(tp); + + subflow->penalise =3D false; + if (cwnd <=3D MPTCP_PENALISE_MIN_CWND || + inet_csk(ssk)->icsk_ca_state !=3D TCP_CA_Open || + !mptcp_penalise_throttle_ok(subflow)) + return; + subflow->last_penalise =3D tcp_jiffies32; + tcp_snd_cwnd_set(tp, max_t(u32, cwnd >> 1, MPTCP_PENALISE_MIN_CWND)); + if (cwnd >=3D tp->snd_ssthresh) + tp->snd_ssthresh =3D max_t(u32, tp->snd_ssthresh >> 1, 2); +} + /* implement the mptcp packet scheduler; * returns the subflow that will transmit the next DSS * additionally updates the rtx timeout @@ -1633,10 +1672,11 @@ struct sock *mptcp_subflow_get_send(struct mptcp_so= ck *msk) struct subflow_send_info send_info[SSK_MODE_MAX]; struct mptcp_subflow_context *subflow; struct sock *sk =3D (struct sock *)msk; - unsigned long pace; + unsigned long pace, max_pace =3D 0; u32 burst, wmem; + bool penal_cand, fast_limited; int i, nr_active =3D 0; - struct sock *ssk; + struct sock *ssk, *fastest =3D NULL; u64 linger_time; long tout =3D 0; =20 @@ -1665,6 +1705,12 @@ struct sock *mptcp_subflow_get_send(struct mptcp_soc= k *msk) continue; } =20 + /* fastest non-backup path; slower ones get throttled below */ + if (!backup && pace > max_pace) { + max_pace =3D pace; + fastest =3D ssk; + } + linger_time =3D div64_u64((u64)READ_ONCE(ssk->sk_wmem_queued) << 32, pac= e); if (linger_time < send_info[backup].linger_time) { send_info[backup].ssk =3D ssk; @@ -1692,12 +1738,22 @@ struct sock *mptcp_subflow_get_send(struct mptcp_so= ck *msk) if (!ssk || !sk_stream_memory_free(ssk)) return NULL; =20 + /* Flag a slow subflow for cwnd halving, applied in the push path */ + subflow =3D mptcp_subflow_ctx(ssk); + penal_cand =3D fastest && ssk !=3D fastest && + subflow->avg_pacing_rate < max_pace / MPTCP_PENALISE_RATE_RATIO; + /* We use data_race() because tcp_cwnd_validate() might change + * is_cwnd_limited under us + */ + fast_limited =3D penal_cand && data_race(tcp_is_cwnd_limited(fastest)); + burst =3D min(MPTCP_SEND_BURST_SIZE, mptcp_wnd_end(msk) - msk->snd_nxt); wmem =3D READ_ONCE(ssk->sk_wmem_queued); + /* the conditions on this subflow are re-checked on apply, under its lock= */ + subflow->penalise =3D burst && fast_limited; if (!burst) return ssk; =20 - subflow =3D mptcp_subflow_ctx(ssk); /* 64-bit arithmetic overflows at high rate with a large queue */ subflow->avg_pacing_rate =3D mul_u64_u64_div_u64(subflow->avg_pacing_rate, wmem, @@ -1759,6 +1815,9 @@ static int __subflow_push_pending(struct sock *sk, st= ruct sock *ssk, struct mptcp_data_frag *dfrag; int len, copied =3D 0, err =3D 0; =20 + if (mptcp_subflow_ctx(ssk)->penalise) + mptcp_penalise_cwnd(ssk); + while ((dfrag =3D mptcp_send_head(sk))) { info->sent =3D dfrag->already_sent; info->limit =3D dfrag->data_len; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 3be60da12924..1d41ab1da2e0 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -605,6 +605,7 @@ struct mptcp_subflow_context { __unused : 9; bool data_avail; bool scheduled; + bool penalise; /* scheduler flagged this subflow for cwnd halving */ bool pm_listener; /* a listener managed by the kernel PM? */ bool fully_established; /* path validated */ bool close_event_done; /* has done the post-closed part, @@ -630,6 +631,7 @@ struct mptcp_subflow_context { */ =20 u32 subflow_id; + u32 last_penalise; /* tcp_jiffies32 of the last cwnd penalty */ =20 long delegated_status; unsigned long fail_tout; --=20 2.34.1 From nobody Thu Nov 5 07:36:18 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=165.173.180.52 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1793186164; b=4miBWA2QajMmkU4NxFPPAEfGmvy+L1NTfCqIB0EJRlEy4VgrMLZKK+2vVs33Hr83ld8t r1FQSvyPGC5TRNueFgQIVzgy504xeA1Dv0okjfFsr3dr87BIEy2OIHh3SN+J23Vp+YqR2 pSC8/eT/PWfRyxju3J2YicxCPOF+kdlQ+/dTKH67grgKXxOTMUwBY+u1aCbQ2S+L+qCXj JId0Fg359AFaCcv4Otf++ZgSMNHbOVCa0jJwrmPjTbJyTfsAKDV4dOX/dDJ3ZfmWqVSZS cTVBp6h79ZyqLjz4eFhS3Kv4TEhv9vYdBjTK0wPISg+jdTni+37/H4AWd3YihS7z3jQ== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793186164; h=DMARC-Filter:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Content-Transfer-Encoding:Message-Id:References: In-Reply-To:To:Cc:X-Mailer:X-ZohoMailClient; bh=7XpYXcj/qNqkUVgiJRTjpAc3WBpmArFHsqKbg+J2F7g=; b=1l+aadilhYFo7A1FJHaOxGzuGWbbHPnBjNvtZRawYZRddeioeiKSks4XXoI5jtYDYWzu 6mEQ+Ofyn7f8Gx5YGkRxMoI+IVecST+736wCk9nLsfUIlQ78Tvk9w97F3WRvvtP/qB5Ri 8Yq/GwaBRqoUQ4CiLdm+z8L4Wejp3bgREsEGdhZDbZdV0Z/p9yz1U4Qhm41V2LW7HwKE4 QLsDyQ5OSdA8ebyrVyyTKsUE7opUPhjpxMdfBUM0UQWNL/GFOODVxvH5laAlHKs99jzS0 WYpiEkvrPCUS+abuBJP8RwoKY+K7DQz2sTckr9T1M3Z8QIbm98sDjG6XKdBqJ3dySjw== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass header.from=mpiricsoftware.com; spf=pass smtp.mailfrom=mpiricsoftware.com; arc=pass header.oldest-pass=0 smtp.remote-ip=165.173.180.52 Received: from sender6-of-o52.zoho.com (sender6-of-o52.zoho.com [165.173.180.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 112E6606A31A for ; Wed, 28 Oct 2026 11:16:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 112E6606A31A Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mpiricsoftware.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mpiricsoftware.com ARC-Seal: i=1; a=rsa-sha256; t=1793186142; cv=none; d=zohomail.com; s=zohoarc; b=AwaVFQl0/R6tbpqD1ygBe4CRLVnu8M+3hJ5eUeTnA9dtA1S3ehux1L8Hnkq4Q1g01mUtUew8+/K143aEy+AbJqB4kC9kY5X4AvPaqrr/9EtR3USUi1arUfRu+qJH/H76HNsw2WhSodkgUwMnqd2215i5XioPEEaRP3/AFyxfLOc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1793186142; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=7XpYXcj/qNqkUVgiJRTjpAc3WBpmArFHsqKbg+J2F7g=; b=bA9tefHlOTN/nhkp/CKdw345f1yP+fhGYVAsL+cM9hYVlXcu19vtz0908uQckCUwiMGYF00LJugQJati2q0LUsQnBDP+bRxrqia69Ngfax5xKDv+slDUXxFvK5Mhd49ykSrmPR/v9xJbU+cIxZKsr28SQfI9iEpNyxbBbh4lMdA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=mpiricsoftware.com; spf=pass smtp.mailfrom=shardul.b@mpiricsoftware.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1793186142; s=mpiric; d=mpiricsoftware.com; i=shardul.b@mpiricsoftware.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=7XpYXcj/qNqkUVgiJRTjpAc3WBpmArFHsqKbg+J2F7g=; b=at3sl37QxYVJqXb1l6M3Pm6H+/mZiAjlIkP0+fnu+Ap9spQbS+CbI3xM044PAWh+ foY9XrocMaWKTOwIp3OpEqw2nVYQsGg8mPadO1o0IgrntY0B+jPAekOF20PCbJOxHzg L4qZzJQHxq2DQLf7YryXDiEQzoII1sg5X0Mm6yyk= Received: by smtp.zohomail.com with SMTPS id 1793186141307682.1539123912338; Wed, 28 Oct 2026 04:15:41 -0700 (PDT) From: Shardul Bankar Date: Wed, 28 Oct 2026 16:45:10 +0530 Subject: [PATCH mptcp-next v5 3/4] mptcp: sched: do not penalise when receive-window-limited X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20261028-mptcp_penalise_send_v2-v5-3-32fb379ce117@mpiricsoftware.com> References: <20261028-mptcp_penalise_send_v2-v5-0-32fb379ce117@mpiricsoftware.com> In-Reply-To: <20261028-mptcp_penalise_send_v2-v5-0-32fb379ce117@mpiricsoftware.com> To: mptcp@lists.linux.dev Cc: "Matthieu Baerts (NGI0)" , Janak Patel , Kalpan Jani , Shardul Bankar , Shardul Bankar , Abdul Wasey X-Mailer: b4 0.15.2 X-ZohoMailClient: External The penalty in the previous patch shifts load off a slow subflow onto the fastest one, which only helps if the fastest path can absorb it. When the connection is receive-window-limited (the receiver's advertised window, not our congestion window, is the bottleneck), the fastest path is capped by that shared window too and cannot send more, so halving the slow path's cwnd just sheds its throughput. Gate on the application's queued data fitting within the send window: penalise only while write_seq <=3D wnd_end. If the application has queued past the window edge the receive window is the binding constraint, so skip the penalty. Neither write_seq (application demand) nor wnd_end (peer window) is derived from cwnd, so the test is not made circular by the window itself suppressing cwnd. Co-developed-by: Matthieu Baerts (NGI0) Signed-off-by: Shardul Bankar Tested-by: Abdul Wasey --- net/mptcp/protocol.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 395f9582ece8..5eef96fa4f3e 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1642,6 +1642,14 @@ static bool mptcp_penalise_throttle_ok(struct mptcp_= subflow_context *subflow) return tcp_jiffies32 - subflow->last_penalise >=3D max_t(u32, rtt, 1); } =20 +/* Like tcp_snd_wnd_test() but without an skb: true while queued data stil= l fits + * the send window, i.e. not receive-window-limited. + */ +static bool mptcp_snd_wnd_test(const struct mptcp_sock *msk) +{ + return !after64(msk->write_seq, mptcp_wnd_end(msk)); +} + /* Halve cwnd, and ssthresh when cwnd is at or above it, under the subflow * socket lock: the scheduler only marks a candidate, the conditions on th= is * subflow are evaluated here, on current state. @@ -1750,7 +1758,7 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock= *msk) burst =3D min(MPTCP_SEND_BURST_SIZE, mptcp_wnd_end(msk) - msk->snd_nxt); wmem =3D READ_ONCE(ssk->sk_wmem_queued); /* the conditions on this subflow are re-checked on apply, under its lock= */ - subflow->penalise =3D burst && fast_limited; + subflow->penalise =3D burst && fast_limited && mptcp_snd_wnd_test(msk); if (!burst) return ssk; =20 --=20 2.34.1 From nobody Thu Nov 5 07:36:18 2026 Authentication-Results: smtp.subspace.kernel.org; arc=pass header.oldest-pass=0 smtp.remote-ip=165.173.180.52 ARC-Seal: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=pass; t=1793186176; b=VqsJU4/yOhFuxpdqm5lJlV0QdWqP+2In3M5+McjmXQ/nyGeaLaWmuTMI3+ZS4s22/BC3 eYPcZJYn+uc0iu9Z3gqu9HH7AtBY6etdcE5p4lUfFnZWw0ySDWGnyyYwUzBBR0JMLUwD4 WJtp2oATzafTRO+Ji90TwvNr2XVokKBEtTHbN0u+7DP75XsDQgMR1KnCUOTbTWXabS9ol a3xd0TIiItlwAIMAZJhgUPPOXrD5Jhg0qocqGaMhJsxnGjVzG3Am1I9cBxl1hq/DR15o1 fWQezBO2yL30yPNT7aYpa1M/AFE1DTIn9Dej6M4+1kVsYJ8aUWVpAnwo/nQWzYOFJHA== ARC-Message-Signature: i=2; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793186176; h=DMARC-Filter:DKIM-Signature:Received:From:Date:Subject:MIME-Version: Content-Type:Content-Transfer-Encoding:Message-Id:References: In-Reply-To:To:Cc:X-Mailer:X-ZohoMailClient; bh=bjo63Po4HnZgVzbwBJLMYyaHXsG3hyUNqmtV9wHK36I=; b=IKgr773UtVZI9PLaJhjnwwAkzfuDKN63aAuC4gGCFPerU3so3w7eZN/8rT6DC0wSMz5o OUn0MiqBvtrfNPuEAD7nWKfdqvh/OqgxkH4F51R1in7BXvnfzOI9mek4eukRrirE1i3wP d7sMqfL69GZ18cMtUCTWdx3GBVmWiPxmYaiXIKAtoHxGSNmI7cjOTU4N6Mvfm4ZpPOqOY 0hwrV0Glnx6hjUURSO9Jyq0IuCPuUT9UaFg4rmZcGgXSpZdHNJkNtP2mKyqY8Ke5XabqW 7NcF7zlVkIDThi0DBV7dytxicSAWbqYgo5Xj3Bla6In1nGHOrbFsZ4/Qhj9NgPiInxg== ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass header.from=mpiricsoftware.com; spf=pass smtp.mailfrom=mpiricsoftware.com; arc=pass header.oldest-pass=0 smtp.remote-ip=165.173.180.52 Received: from sender6-of-o52.zoho.com (sender6-of-o52.zoho.com [165.173.180.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48A0B606A31D for ; Wed, 28 Oct 2026 11:16:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 48A0B606A31D Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mpiricsoftware.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mpiricsoftware.com ARC-Seal: i=1; a=rsa-sha256; t=1793186146; cv=none; d=zohomail.com; s=zohoarc; b=lL9ZG7SvbEUKnWffA1xe+9uyJpNhrr9paGoBIj0Ks13tTP+w7rLhPUIqMNIW5ZXslFuytF3dKNwJNnWLKiW1ENlp2Gw+BZa4IRQik+bQ/lObpW52rcMx4BAFUD2IO3g43DyxSJjcXhzEIpMfXgJTtGs6owzkGOOFloh2rhGTpcc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1793186146; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=bjo63Po4HnZgVzbwBJLMYyaHXsG3hyUNqmtV9wHK36I=; b=jVo4jq8J74HVjz1CjO290t4lLFVdbc2FQqMJU89K9c5DS0trh7+04B0UCwBt4EufU66Q9A8JlQUb/9v5yjD3zTTr7RQd+PDvzV9N2m98Z6TdL5Nym+Rt73YZTvG2S8EiaOcqPUmN+hEGLDQS0p6uA2Y9NlbEf1cpirG8bjfJdGY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=mpiricsoftware.com; spf=pass smtp.mailfrom=shardul.b@mpiricsoftware.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1793186146; s=mpiric; d=mpiricsoftware.com; i=shardul.b@mpiricsoftware.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=bjo63Po4HnZgVzbwBJLMYyaHXsG3hyUNqmtV9wHK36I=; b=fUCKM/nl355WbbipRnQpOIYdv+KV8N+qaoQMpeuxjz93atQ6moWGwlUmsOECaytR rJKSMtopNxv9yvEwv7mmtxWYd4xCI166KIvS+GDGQfj+XtK/zxDm4/OB68GCcQv8s0Q 0bJSBD6FgncCLLID3OZOb7vYnV/r+5M6ii0vp6JI= Received: by smtp.zohomail.com with SMTPS id 1793186144423313.807320454046; Wed, 28 Oct 2026 04:15:44 -0700 (PDT) From: Shardul Bankar Date: Wed, 28 Oct 2026 16:45:11 +0530 Subject: [PATCH mptcp-next v5 4/4] mptcp: sched: add penalise counters and tracepoint X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20261028-mptcp_penalise_send_v2-v5-4-32fb379ce117@mpiricsoftware.com> References: <20261028-mptcp_penalise_send_v2-v5-0-32fb379ce117@mpiricsoftware.com> In-Reply-To: <20261028-mptcp_penalise_send_v2-v5-0-32fb379ce117@mpiricsoftware.com> To: mptcp@lists.linux.dev Cc: "Matthieu Baerts (NGI0)" , Janak Patel , Kalpan Jani , Shardul Bankar , Shardul Bankar , Abdul Wasey X-Mailer: b4 0.15.2 X-ZohoMailClient: External Add observability for the cwnd-halving penalty introduced in the previous patches. Two MPTcpExt SNMP counters: - CwndPenalised: times a subflow cwnd was actually halved; - PenalCandidate: times the rate trigger picked a slow subflow. The two together show how often the rate trigger fired and how many of those candidates were actually halved. The difference is the combined effect of the remaining conditions, so it does not isolate any one of them. Add a mptcp_subflow_penalise tracepoint. The penalise verdict is decided after the subflow-selection loop, once the fastest path is known, so it is exposed through a dedicated tracepoint rather than the per-candidate mptcp_subflow_get_send emit. It reports the selected subflow's pace, the fastest path's pace, its cwnd and the send burst alongside the verdict, so a slow subflow and its window can be watched from a single line. The verdict is emitted once the send burst is known, so it accounts for the window check. The conditions local to the subflow are evaluated later, under that subflow's own lock, so a set verdict here means the scheduler picked the subflow as a candidate; CwndPenalised remains the count of penalties actually applied. Co-developed-by: Matthieu Baerts (NGI0) Signed-off-by: Shardul Bankar Tested-by: Abdul Wasey --- include/trace/events/mptcp.h | 33 +++++++++++++++++++++++++++++++++ net/mptcp/mib.c | 2 ++ net/mptcp/mib.h | 2 ++ net/mptcp/protocol.c | 4 ++++ 4 files changed, 41 insertions(+) diff --git a/include/trace/events/mptcp.h b/include/trace/events/mptcp.h index c47fa2672b84..de34e107e202 100644 --- a/include/trace/events/mptcp.h +++ b/include/trace/events/mptcp.h @@ -68,6 +68,39 @@ TRACE_EVENT(mptcp_subflow_get_send, __entry->backup, __entry->ratio) ); =20 +TRACE_EVENT(mptcp_subflow_penalise, + + TP_PROTO(struct mptcp_subflow_context *subflow, unsigned long max_pace, + u32 burst), + + TP_ARGS(subflow, max_pace, burst), + + TP_STRUCT__entry( + __field(u64, pace) + __field(u64, max_pace) + __field(u32, cwnd) + __field(u32, burst) + __field(bool, penalise) + ), + + TP_fast_assign( + struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); + + __entry->pace =3D subflow->avg_pacing_rate; + __entry->max_pace =3D max_pace; + if (ssk && sk_fullsock(ssk)) + __entry->cwnd =3D tcp_snd_cwnd(tcp_sk(ssk)); + else + __entry->cwnd =3D 0; + __entry->burst =3D burst; + __entry->penalise =3D subflow->penalise; + ), + + TP_printk("pace=3D%llu max_pace=3D%llu cwnd=3D%u burst=3D%u penalise=3D%d= ", + __entry->pace, __entry->max_pace, + __entry->cwnd, __entry->burst, __entry->penalise) +); + DECLARE_EVENT_CLASS(mptcp_dump_mpext, =20 TP_PROTO(struct mptcp_ext *mpext), diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c index 608cb568897c..b39b5511345d 100644 --- a/net/mptcp/mib.c +++ b/net/mptcp/mib.c @@ -95,6 +95,8 @@ static const struct snmp_mib mptcp_snmp_list[] =3D { SNMP_MIB_ITEM("BacklogDrop", MPTCP_MIB_BACKLOGDROP), SNMP_MIB_ITEM("RcvPruned", MPTCP_MIB_RCVPRUNED), SNMP_MIB_ITEM("OFOPruned", MPTCP_MIB_OFOPRUNED), + SNMP_MIB_ITEM("CwndPenalised", MPTCP_MIB_CWNDPENALISED), + SNMP_MIB_ITEM("PenalCandidate", MPTCP_MIB_PENALCAND), }; =20 /* mptcp_mib_alloc - allocate percpu mib counters diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h index 1ebdb55e9534..a7b5bf684af7 100644 --- a/net/mptcp/mib.h +++ b/net/mptcp/mib.h @@ -98,6 +98,8 @@ enum linux_mptcp_mib_field { MPTCP_MIB_BACKLOGDROP, /* Backlog over memory limit */ MPTCP_MIB_RCVPRUNED, /* Dropped due to memory constraints */ MPTCP_MIB_OFOPRUNED, /* MPTCP-level OoO queue pruned */ + MPTCP_MIB_CWNDPENALISED, /* subflow cwnd halved by the scheduler */ + MPTCP_MIB_PENALCAND, /* scheduler picked a slow (low-rate) subflow */ __MPTCP_MIB_MAX }; =20 diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 5eef96fa4f3e..8f3c6ebd49ee 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1667,6 +1667,7 @@ static void mptcp_penalise_cwnd(struct sock *ssk) return; subflow->last_penalise =3D tcp_jiffies32; tcp_snd_cwnd_set(tp, max_t(u32, cwnd >> 1, MPTCP_PENALISE_MIN_CWND)); + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_CWNDPENALISED); if (cwnd >=3D tp->snd_ssthresh) tp->snd_ssthresh =3D max_t(u32, tp->snd_ssthresh >> 1, 2); } @@ -1750,6 +1751,8 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock= *msk) subflow =3D mptcp_subflow_ctx(ssk); penal_cand =3D fastest && ssk !=3D fastest && subflow->avg_pacing_rate < max_pace / MPTCP_PENALISE_RATE_RATIO; + if (penal_cand) + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_PENALCAND); /* We use data_race() because tcp_cwnd_validate() might change * is_cwnd_limited under us */ @@ -1759,6 +1762,7 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock= *msk) wmem =3D READ_ONCE(ssk->sk_wmem_queued); /* the conditions on this subflow are re-checked on apply, under its lock= */ subflow->penalise =3D burst && fast_limited && mptcp_snd_wnd_test(msk); + trace_mptcp_subflow_penalise(subflow, max_pace, burst); if (!burst) return ssk; =20 --=20 2.34.1