All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support
@ 2026-11-02  2:58 Geliang Tang
  2026-11-02  2:58 ` [PATCH mptcp-next v4 1/5] mptcp: update mptcp_check_readable Geliang Tang
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Geliang Tang @ 2026-11-02  2:58 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

v4:
 - patch 2: fix mptcp_inq_hint() to return 0 instead of INT_MAX on
   passive TFO overflow (ack_seq - map_seq >= INT_MAX).
 - patch 4: add mptcp_rtx_head(sk) to the early-return check in
   mptcp_rate_check_app_limited() so pending retransmissions also
   prevent false app-limited marking.
 - patch 5: update comment message.

v3:
 - patch 2: drop DATA_FIN subtraction in mptcp_inq(), remove the
   intermediate 'answ' variable and return (unsigned int)avail
   directly. Update commit message accordingly.
 - https://patchwork.kernel.org/project/mptcp/cover/cover.1793324316.git.tanggeliang@kylinos.cn/

v2:
 - drop the patch "prevent dummy DATA_FIN on RST in fallback mode".
 - keep mptcp_inq_hint in mptcp_ioctl unchanged.
 - use mptcp_data_avail in mptcp_inq.
 - add msk_owned_by_me check in mptcp_sendmsg_locked.
 - https://patchwork.kernel.org/project/mptcp/cover/cover.1793258749.git.tanggeliang@kylinos.cn/

v1:
 - https://patchwork.kernel.org/project/mptcp/cover/cover.1792999988.git.tanggeliang@kylinos.cn/

This series was previously posted as part of "Reduce the differences
between TCP and MPTCP for TLS usage" v15. It creates the mptcp_inq()
and mptcp_sendmsg_locked() interfaces that are required for the upcoming
MPTCP kTLS and MPTCP sockmap implementations.

The series has been rebased and no longer depends on Paolo's CB layout
refactoring patches (mptcp: drop the mptcp_ooo_try_coalesce() helper,
mptcp: drop the cant_coalesce CB field, mptcp: remove CB offset field,
mptcp: sync mptcp skb cb layout with tcp one, mptcp: defer read_sock
cleanup to mptcp_worker). Those patches are more complex and will be
sent in a separate series.

Patch overview:

1. mptcp: update mptcp_check_readable
 - Align with TCP's sock_is_readable for better TLS compatibility

2. mptcp: prevent dummy DATA_FIN on RST in fallback mode
 - Fix semantic issue where RST on fallback connections would create
   dummy DATA_FIN, causing unnecessary state transitions
 - Add sk_err check to subflow_is_done() to distinguish abortive
   closes (RST) from clean closes (FIN)

3. mptcp: implement peek_len for proto_ops
 - Add mptcp_inq() to report readable bytes at MPTCP level
 - Wire into .peek_len proto_ops for both IPv4 and IPv6
 - Handle 32-bit torn reads by returning 0 instead of INT_MAX
 - Prepare for TLS strparser integration

4. mptcp: add sendmsg_locked to proto_ops
 - Split mptcp_sendmsg() into locked/unlocked variants
 - Expose .sendmsg_locked in proto_ops for TLS send path

5. mptcp: track app-limited state in mptcp_sendmsg
 - Add mptcp_rate_check_app_limited() to mark subflows as app-limited
 - Bail out when MPTCP has unsent data (write_seq != snd_nxt or
   mptcp_send_head() != NULL) to avoid false app-limited marking
 - Enable accurate delivery rate estimation for BBR

6. selftests: mptcp: sockopt: check app_limited
 - Add regression test for app-limited accounting
 - Verify tcpi_delivery_rate_app_limited == 1 after small transfers

Gang Yan (1):
  mptcp: update mptcp_check_readable

Geliang Tang (4):
  mptcp: implement peek_len for proto_ops
  mptcp: add sendmsg_locked to proto_ops
  mptcp: track app-limited state in mptcp_sendmsg
  selftests: mptcp: sockopt: check app_limited

 net/mptcp/protocol.c                          | 75 +++++++++++++++++--
 .../selftests/net/mptcp/mptcp_sockopt.c       |  5 ++
 2 files changed, 72 insertions(+), 8 deletions(-)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH mptcp-next v4 1/5] mptcp: update mptcp_check_readable
  2026-11-02  2:58 [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support Geliang Tang
@ 2026-11-02  2:58 ` Geliang Tang
  2026-11-02  2:58 ` [PATCH mptcp-next v4 2/5] mptcp: implement peek_len for proto_ops Geliang Tang
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Geliang Tang @ 2026-11-02  2:58 UTC (permalink / raw)
  To: mptcp; +Cc: Gang Yan, Geliang Tang

From: Gang Yan <yangang@kylinos.cn>

This patch makes mptcp_check_readable() aligned with TCP, and renames it to
mptcp_stream_is_readable(). It will be used in the case of KTLS, because
'prot' will be modified, tls_sw_sock_is_readable() is expected to be called
from prot->sock_is_readable().

Co-developed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
---
 net/mptcp/protocol.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 02a4f479d9d8..0caa31525b90 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3476,9 +3476,11 @@ void __mptcp_unaccepted_force_close(struct sock *sk)
 	__mptcp_destroy_sock(sk);
 }
 
-static __poll_t mptcp_check_readable(struct sock *sk)
+static bool mptcp_stream_is_readable(struct sock *sk)
 {
-	return mptcp_epollin_ready(sk) ? EPOLLIN | EPOLLRDNORM : 0;
+	if (mptcp_epollin_ready(sk))
+		return true;
+	return sk_is_readable(sk);
 }
 
 static void mptcp_check_listen_stop(struct sock *sk)
@@ -4580,7 +4582,8 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
 		mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
 
 	if (state != TCP_SYN_SENT && state != TCP_SYN_RECV) {
-		mask |= mptcp_check_readable(sk);
+		if (mptcp_stream_is_readable(sk))
+			mask |= EPOLLIN | EPOLLRDNORM;
 		if (shutdown & SEND_SHUTDOWN)
 			mask |= EPOLLOUT | EPOLLWRNORM;
 		else
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH mptcp-next v4 2/5] mptcp: implement peek_len for proto_ops
  2026-11-02  2:58 [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support Geliang Tang
  2026-11-02  2:58 ` [PATCH mptcp-next v4 1/5] mptcp: update mptcp_check_readable Geliang Tang
@ 2026-11-02  2:58 ` Geliang Tang
  2026-11-02  3:19   ` sashiko-bot
  2026-11-02  2:58 ` [PATCH mptcp-next v4 3/5] mptcp: add sendmsg_locked to proto_ops Geliang Tang
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Geliang Tang @ 2026-11-02  2:58 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang, Zqiang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add mptcp_inq() to compute readable bytes at the MPTCP level using
mptcp_data_avail() (bytes_received - bytes_consumed) to avoid TFO
overflow issues. Returns 0 during handshake or when avail >= INT_MAX.

Wire into mptcp_peek_len() and assign .peek_len in both mptcp_stream_ops
and mptcp_v6_stream_ops.

Also fix mptcp_inq_hint() to return 0 instead of INT_MAX when ack_seq
minus the head skb's map_seq overflows. On passive TFO the head skb has
map_seq = -skb->len while ack_seq is later set to iasn, so the subtraction
overflows INT_MAX. Returning 0 prevents SIOCINQ from reporting 2GB and
stops mptcp_rcv_space_adjust() from skipping autotuning.

Co-developed-by: Zqiang <qiang.zhang@linux.dev>
Signed-off-by: Zqiang <qiang.zhang@linux.dev>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/protocol.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 0caa31525b90..c6d354900e7d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2409,7 +2409,7 @@ static unsigned int mptcp_inq_hint(const struct sock *sk)
 		u64 hint_val = READ_ONCE(msk->ack_seq) - MPTCP_SKB_CB(skb)->map_seq;
 
 		if (hint_val >= INT_MAX)
-			return INT_MAX;
+			return 0;
 
 		return (unsigned int)hint_val;
 	}
@@ -4797,6 +4797,26 @@ static ssize_t mptcp_splice_read(struct socket *sock, loff_t *ppos,
 	return ret;
 }
 
+static int mptcp_inq(struct sock *sk)
+{
+	const struct mptcp_sock *msk = mptcp_sk(sk);
+	u64 avail;
+
+	if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))
+		return 0;
+
+	avail = mptcp_data_avail(msk);
+	if (avail >= INT_MAX)
+		return 0;
+
+	return (unsigned int)avail;
+}
+
+static int mptcp_peek_len(struct socket *sock)
+{
+	return mptcp_inq(sock->sk);
+}
+
 static const struct proto_ops mptcp_stream_ops = {
 	.family		   = PF_INET,
 	.owner		   = THIS_MODULE,
@@ -4819,6 +4839,7 @@ static const struct proto_ops mptcp_stream_ops = {
 	.set_rcvlowat	   = mptcp_set_rcvlowat,
 	.read_sock	   = mptcp_read_sock,
 	.splice_read	   = mptcp_splice_read,
+	.peek_len	   = mptcp_peek_len,
 };
 
 static struct inet_protosw mptcp_protosw = {
@@ -4931,6 +4952,7 @@ static const struct proto_ops mptcp_v6_stream_ops = {
 	.set_rcvlowat	   = mptcp_set_rcvlowat,
 	.read_sock	   = mptcp_read_sock,
 	.splice_read	   = mptcp_splice_read,
+	.peek_len	   = mptcp_peek_len,
 };
 
 static struct proto mptcp_v6_prot;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH mptcp-next v4 3/5] mptcp: add sendmsg_locked to proto_ops
  2026-11-02  2:58 [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support Geliang Tang
  2026-11-02  2:58 ` [PATCH mptcp-next v4 1/5] mptcp: update mptcp_check_readable Geliang Tang
  2026-11-02  2:58 ` [PATCH mptcp-next v4 2/5] mptcp: implement peek_len for proto_ops Geliang Tang
@ 2026-11-02  2:58 ` Geliang Tang
  2026-11-02  2:58 ` [PATCH mptcp-next v4 4/5] mptcp: track app-limited state in mptcp_sendmsg Geliang Tang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Geliang Tang @ 2026-11-02  2:58 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

MPTCP currently provides a standard sendmsg() implementation which
acquires and releases the socket lock internally. However, certain
upper layers need to call the sendmsg method while the socket lock
is already held.

Split the existing mptcp_sendmsg() into mptcp_sendmsg_locked() which
assumes the caller holds the socket lock, and a tiny wrapper
mptcp_sendmsg() that acquires the lock and calls the locked version.
Add msk_owned_by_me() assertion to enforce the locking requirement.
Expose .sendmsg_locked in both mptcp_stream_ops and mptcp_v6_stream_ops.

This prepares for upcoming kTLS and sockmap support.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/protocol.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index c6d354900e7d..7ccb1c7506a3 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2038,7 +2038,7 @@ static void mptcp_rps_record_subflows(const struct mptcp_sock *msk)
 	}
 }
 
-static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+static int mptcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len)
 {
 	struct mptcp_sock *msk = mptcp_sk(sk);
 	struct page_frag *pfrag;
@@ -2046,12 +2046,12 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	int ret = 0;
 	long timeo;
 
+	msk_owned_by_me(msk);
+
 	/* silently ignore everything else */
 	msg->msg_flags &= MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
 			  MSG_FASTOPEN | MSG_EOR;
 
-	lock_sock(sk);
-
 	mptcp_rps_record_subflows(msk);
 
 	if (unlikely(inet_test_bit(DEFER_CONNECT, sk) ||
@@ -2167,7 +2167,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	}
 
 out:
-	release_sock(sk);
 	return copied;
 
 do_error:
@@ -2180,6 +2179,17 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	goto out;
 }
 
+static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+{
+	int ret;
+
+	lock_sock(sk);
+	ret = mptcp_sendmsg_locked(sk, msg, len);
+	release_sock(sk);
+
+	return ret;
+}
+
 static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied);
 
 static void mptcp_eat_recv_skb(struct sock *sk, struct sk_buff *skb)
@@ -4840,6 +4850,7 @@ static const struct proto_ops mptcp_stream_ops = {
 	.read_sock	   = mptcp_read_sock,
 	.splice_read	   = mptcp_splice_read,
 	.peek_len	   = mptcp_peek_len,
+	.sendmsg_locked	   = mptcp_sendmsg_locked,
 };
 
 static struct inet_protosw mptcp_protosw = {
@@ -4953,6 +4964,7 @@ static const struct proto_ops mptcp_v6_stream_ops = {
 	.read_sock	   = mptcp_read_sock,
 	.splice_read	   = mptcp_splice_read,
 	.peek_len	   = mptcp_peek_len,
+	.sendmsg_locked	   = mptcp_sendmsg_locked,
 };
 
 static struct proto mptcp_v6_prot;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH mptcp-next v4 4/5] mptcp: track app-limited state in mptcp_sendmsg
  2026-11-02  2:58 [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support Geliang Tang
                   ` (2 preceding siblings ...)
  2026-11-02  2:58 ` [PATCH mptcp-next v4 3/5] mptcp: add sendmsg_locked to proto_ops Geliang Tang
@ 2026-11-02  2:58 ` Geliang Tang
  2026-11-02  3:13   ` sashiko-bot
  2026-11-02  2:58 ` [PATCH mptcp-next v4 5/5] selftests: mptcp: sockopt: check app_limited Geliang Tang
  2026-11-02  5:03 ` [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support MPTCP CI
  5 siblings, 1 reply; 9+ messages in thread
From: Geliang Tang @ 2026-11-02  2:58 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

Add mptcp_rate_check_app_limited() that walks every subflow and runs
tcp_rate_check_app_limited() under each subflow's socket lock. The
helper bails out early when MPTCP still has data to send: unsent data
(write_seq != snd_nxt), skbs on the send queue (mptcp_send_head), or
data awaiting retransmission (mptcp_rtx_head). In these cases marking
subflows app-limited would mislead congestion controllers.

Invoke from mptcp_sendmsg_locked() after send-side setup so BBR and
similar controllers can ignore rate samples taken while the connection
is genuinely application-limited.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/protocol.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 7ccb1c7506a3..ab7de11a448c 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2038,6 +2038,25 @@ static void mptcp_rps_record_subflows(const struct mptcp_sock *msk)
 	}
 }
 
+static void mptcp_rate_check_app_limited(struct sock *sk)
+{
+	struct mptcp_sock *msk = mptcp_sk(sk);
+	struct mptcp_subflow_context *subflow;
+
+	if (msk->write_seq != msk->snd_nxt ||
+	    mptcp_send_head(sk) || mptcp_rtx_head(sk))
+		return;
+
+	mptcp_for_each_subflow(msk, subflow) {
+		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+		bool slow;
+
+		slow = lock_sock_fast_nested(ssk);
+		tcp_rate_check_app_limited(ssk);
+		unlock_sock_fast(ssk, slow);
+	}
+}
+
 static int mptcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len)
 {
 	struct mptcp_sock *msk = mptcp_sk(sk);
@@ -2068,6 +2087,9 @@ static int mptcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len)
 
 	timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
 
+	/* is sending application-limited? */
+	mptcp_rate_check_app_limited(sk);
+
 	if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) {
 		ret = sk_stream_wait_connect(sk, &timeo);
 		if (ret)
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH mptcp-next v4 5/5] selftests: mptcp: sockopt: check app_limited
  2026-11-02  2:58 [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support Geliang Tang
                   ` (3 preceding siblings ...)
  2026-11-02  2:58 ` [PATCH mptcp-next v4 4/5] mptcp: track app-limited state in mptcp_sendmsg Geliang Tang
@ 2026-11-02  2:58 ` Geliang Tang
  2026-11-02  5:03 ` [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support MPTCP CI
  5 siblings, 0 replies; 9+ messages in thread
From: Geliang Tang @ 2026-11-02  2:58 UTC (permalink / raw)
  To: mptcp; +Cc: Geliang Tang

From: Geliang Tang <tanggeliang@kylinos.cn>

After a small data exchange, assert tcpi_delivery_rate_app_limited == 1.

rate_app_limited starts at 1 (tcp_init_sock) and is cleared only by
non-app-limited rate samples. The preceding commit makes
mptcp_rate_check_app_limited() set tp->app_limited on subflows when
MPTCP has no pending data, marking outgoing skbs as app-limited so rate
samples don't clear rate_app_limited.

This guards against regressions in subflow app-limited accounting.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 tools/testing/selftests/net/mptcp/mptcp_sockopt.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index b8158a1198eb..9517c530ba21 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -635,6 +635,11 @@ static void connect_one_server(int fd, int pipefd)
 	do_getsockopts(&s, fd, total, total);
 
 	assert(s.mptcpi_rcv_delta == (uint64_t)total);
+
+	/* app-limited accounting only checked under EXPECT_ALL_FEATURES */
+	if (expect_all_features())
+		assert(s.tcp_info.tcpi_delivery_rate_app_limited == 1);
+
 	close(fd);
 }
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH mptcp-next v4 4/5] mptcp: track app-limited state in mptcp_sendmsg
  2026-11-02  2:58 ` [PATCH mptcp-next v4 4/5] mptcp: track app-limited state in mptcp_sendmsg Geliang Tang
@ 2026-11-02  3:13   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-11-02  3:13 UTC (permalink / raw)
  To: Geliang Tang, mptcp

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] mptcp: mptcp_rate_check_app_limited() bails out when data is in flight
- [Medium] mptcp: unlocked msk->snd_una read in mptcp_rate_check_app_limited()
--

commit 6075a59b5fc2bd09596bbf554a3f811da115a224
Author: Geliang Tang <geliang@kernel.org>

mptcp: track app-limited state in mptcp_sendmsg

This commit adds mptcp_rate_check_app_limited() to run
tcp_rate_check_app_limited() across all subflows from mptcp_sendmsg_locked()
when no unsent data is queued at the MPTCP level.

> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 7ccb1c7506a37..ab7de11a448ce 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -2038,6 +2038,25 @@ static void mptcp_rps_record_subflows(const struct mptcp_sock *msk)
>  	}
>  }
>  
> +static void mptcp_rate_check_app_limited(struct sock *sk)
> +{
> +	struct mptcp_sock *msk = mptcp_sk(sk);
> +	struct mptcp_subflow_context *subflow;
> +
> +	if (msk->write_seq != msk->snd_nxt ||
> +	    mptcp_send_head(sk) || mptcp_rtx_head(sk))
> +		return;

[Severity: Medium]
Does checking mptcp_rtx_head(sk) here prevent subflows from being marked
application-limited whenever any sent data is still in flight?

Every sent mptcp_data_frag stays on msk->rtx_queue until a DATA_ACK advances
msk->snd_una past it and __mptcp_clean_una() removes it, so mptcp_rtx_head()
returns non-NULL whenever msk->snd_una != msk->snd_nxt:

net/mptcp/protocol.h:mptcp_rtx_head() {
	struct mptcp_sock *msk = mptcp_sk(sk);

	if (msk->snd_una == msk->snd_nxt)
		return NULL;

	return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list);
}

In contrast, tcp_rate_check_app_limited() is designed to run while packets are
in flight below cwnd (tcp_packets_in_flight(tp) < tcp_snd_cwnd(tp)) and
already checks tp->lost_out <= tp->retrans_out on each subflow, while
MPTCP-level reinjection in __mptcp_retransmit_pending_data() resets
msk->first_pending (which is covered by mptcp_send_head(sk)). With the
mptcp_rtx_head(sk) check in place, won't mptcp_rate_check_app_limited() bail
out whenever any unacknowledged data is in flight on the connection?

[Severity: Medium]
Additionally, is it safe to call mptcp_rtx_head(sk) from
mptcp_sendmsg_locked() -> mptcp_rate_check_app_limited() without holding
mptcp_data_lock(sk)?

mptcp_rtx_head() performs a plain 64-bit read of msk->snd_una, whereas
incoming DATA_ACK processing in softirq context updates msk->snd_una under
mptcp_data_lock(sk) even while the user owns the msk socket lock:

mptcp_incoming_options()
  ack_update_msk()
    mptcp_data_lock(sk)
    __mptcp_snd_una_update()
      WRITE_ONCE(msk->snd_una, new_snd_una);

Other callers of mptcp_rtx_head() (__mptcp_clean_una(),
__mptcp_retransmit_pending_data(), and __mptcp_retrans()) hold
mptcp_data_lock(sk), and helpers that read msk->snd_una under only the msk
socket lock use READ_ONCE(msk->snd_una). Can this cause a data race or 64-bit
load tearing on 32-bit architectures?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1793588257.git.tanggeliang@kylinos.cn?part=4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH mptcp-next v4 2/5] mptcp: implement peek_len for proto_ops
  2026-11-02  2:58 ` [PATCH mptcp-next v4 2/5] mptcp: implement peek_len for proto_ops Geliang Tang
@ 2026-11-02  3:19   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-11-02  3:19 UTC (permalink / raw)
  To: Geliang Tang, mptcp

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] mptcp: incorrect readable byte count in mptcp_inq_hint() on passive TFO
--

commit c2b974abec7822444a7f621944b513eb168889a9
Author: Geliang Tang <geliang@kernel.org>

mptcp: implement peek_len for proto_ops

This commit implements the peek_len callback for mptcp_stream_ops and
mptcp_v6_stream_ops using mptcp_data_avail(). It also changes
mptcp_inq_hint() to return 0 instead of INT_MAX when msk->ack_seq minus the
head skb's map_seq is at least INT_MAX.

> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 0caa31525b907..c6d354900e7d2 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -2409,7 +2409,7 @@ static unsigned int mptcp_inq_hint(const struct sock *sk)
>  		u64 hint_val = READ_ONCE(msk->ack_seq) - MPTCP_SKB_CB(skb)->map_seq;
>  
>  		if (hint_val >= INT_MAX)
> -			return INT_MAX;
> +			return 0;
>  
>  		return (unsigned int)hint_val;
>  	}

[Severity: Medium]
On passive TFO connections, won't returning 0 here cause mptcp_inq_hint() to
report 0 readable bytes (or a bogus subflow->iasn-derived value when hint_val
wraps below INT_MAX) even when unread data is queued in sk->sk_receive_queue?

During passive TFO, mptcp_fastopen_subflow_synack_set_params() queues the SYN
payload skb onto sk->sk_receive_queue with map_seq = -skb->len and increments
msk->bytes_received by skb->len while msk->ack_seq is 0:

net/mptcp/fastopen.c:mptcp_fastopen_subflow_synack_set_params() {
	...
	/* Only the sequence delta is relevant */
	MPTCP_SKB_CB(skb)->map_seq = -skb->len;
	MPTCP_SKB_CB(skb)->end_seq = 0;
	MPTCP_SKB_CB(skb)->offset = 0;
	...
}

When the third ACK carrying MP_CAPABLE_ACK arrives,
__mptcp_subflow_fully_established() -> subflow_set_remote_key() sets
msk->ack_seq to subflow->iasn without rebasing the TFO head skb's map_seq:

net/mptcp/subflow.c:subflow_set_remote_key() {
	...
	WRITE_ONCE(msk->remote_key, subflow->remote_key);
	WRITE_ONCE(msk->ack_seq, subflow->iasn);
	...
}

While any unconsumed bytes of the TFO skb remain at the head of
sk->sk_receive_queue (before the first read, during MSG_PEEK, or after a
partial read), mptcp_inq_hint() computes:

	hint_val = READ_ONCE(msk->ack_seq) - MPTCP_SKB_CB(skb)->map_seq;

which evaluates to subflow->iasn + mptcp_data_avail(msk) (mod 2^64).

When hint_val >= INT_MAX, mptcp_inq_hint() returns 0 despite unread data
sitting in sk->sk_receive_queue, and when the 64-bit sum wraps below INT_MAX,
it returns a bogus byte count up to INT_MAX - 1. This causes SIOCINQ in
mptcp_ioctl() and the TCP_CM_INQ cmsg in mptcp_recvmsg() to report an
incorrect readable byte count to userspace, and causes
mptcp_rcv_space_adjust() to subtract 0 (or a bogus iasn offset) instead of
the unread receive queue occupancy.

Should mptcp_inq_hint() compute the available bytes using
mptcp_data_avail(msk) like mptcp_inq() does?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1793588257.git.tanggeliang@kylinos.cn?part=2

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support
  2026-11-02  2:58 [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support Geliang Tang
                   ` (4 preceding siblings ...)
  2026-11-02  2:58 ` [PATCH mptcp-next v4 5/5] selftests: mptcp: sockopt: check app_limited Geliang Tang
@ 2026-11-02  5:03 ` MPTCP CI
  5 siblings, 0 replies; 9+ messages in thread
From: MPTCP CI @ 2026-11-02  5:03 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp

Hi Geliang,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Unstable: 3 failed test(s): bpftest_test_progs-cpuv4_mptcp bpftest_test_progs-no_alu32_mptcp bpftest_test_progs_mptcp ⚠️ 
- KVM Validation: btf-debug (only bpftest_all): Unstable: 3 failed test(s): bpftest_test_progs-cpuv4_mptcp bpftest_test_progs-no_alu32_mptcp bpftest_test_progs_mptcp ⚠️ 
- Perf: Unstable: 1 failed test(s): error:sched-mem-pressure ⚠️ 
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/41382640238

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/64955a4259e9
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1198394


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-11-02  5:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-02  2:58 [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support Geliang Tang
2026-11-02  2:58 ` [PATCH mptcp-next v4 1/5] mptcp: update mptcp_check_readable Geliang Tang
2026-11-02  2:58 ` [PATCH mptcp-next v4 2/5] mptcp: implement peek_len for proto_ops Geliang Tang
2026-11-02  3:19   ` sashiko-bot
2026-11-02  2:58 ` [PATCH mptcp-next v4 3/5] mptcp: add sendmsg_locked to proto_ops Geliang Tang
2026-11-02  2:58 ` [PATCH mptcp-next v4 4/5] mptcp: track app-limited state in mptcp_sendmsg Geliang Tang
2026-11-02  3:13   ` sashiko-bot
2026-11-02  2:58 ` [PATCH mptcp-next v4 5/5] selftests: mptcp: sockopt: check app_limited Geliang Tang
2026-11-02  5:03 ` [PATCH mptcp-next v4 0/5] prepare interfaces for kTLS and sockmap support MPTCP CI

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.