All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Abeni <pabeni@redhat.com>
To: Geliang Tang <geliang@kernel.org>, mptcp@lists.linux.dev
Cc: Geliang Tang <tanggeliang@kylinos.cn>
Subject: Re: [PATCH mptcp-next 6/6] mptcp: defer sk_data_ready to the worker
Date: Wed, 29 Jul 2026 10:55:03 +0200	[thread overview]
Message-ID: <4fade36e-9dd5-4c53-8cb3-e07c66b387b5@redhat.com> (raw)
In-Reply-To: <5ab5630bc288d5af26ecacfcf29c7fe35f1fd670.1785150300.git.tanggeliang@kylinos.cn>

On 7/27/26 1:29 PM, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
> 
> When MPTCP carries TLS, the data path runs under mptcp_data_lock().
> Reaching sk->sk_data_ready(sk) synchronously ends up at
> tls_strp_check_rcv() -> mptcp_recv_skb() -> mptcp_move_skbs(), which
> calls mptcp_data_lock() on the same sk and recurses on sk_lock.slock.

Is mptcp_move_skbs() really needed in mptcp_recv_skb()? Anyway it looks 
like that is not the only constraint: AFAICS, before the mptcp_recv_skb() 
calls, the TLS code would call __mptcp_read_sock() which in turns calls  
mptcp_rcv_space_adjust() and mptcp_cleanup_rbuf() that requires holding 
the msk socket lock in process context, while the mptcp/TLS caller is in 
BH scope.

> Fix this by deferring sk->sk_data_ready(sk) to mptcp_worker() via a
> new MPTCP_WORK_DATA_READY bit, re-using the existing
> mptcp_schedule_work()/mptcp_cancel_work() infrastructure. The wakeup
> bit is consumed after the SOCK_DEAD && TCP_CLOSE destroy branch, so a
> socket that reaches the destroy path drops the pending wakeup rather
> than running it post-free.

I think that unconditionally adding the work latency for non-TLS application 
is a no-go.

Instead I *think* that the constraints in __mptcp_read_sock() could be relaxed
with something alike the following (completely untested):
---
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index ca644ec53eed..b09e267f5d46 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2986,6 +2986,15 @@ static void mptcp_do_fastclose(struct sock *sk)
 	}
 }
 
+static void mptcp_read_complete(struct sock *sk)
+{
+	struct mptcp_sock *msk = mptcp_sk(sk);
+
+	mptcp_cleanup_rbuf(msk, msk->read_copied);
+	mptcp_rcv_space_adjust(msk, msk->read_copied);
+	msk->read_copied = 0;
+}
+
 static void mptcp_worker(struct work_struct *work)
 {
 	struct mptcp_sock *msk = container_of(work, struct mptcp_sock, work);
@@ -3026,6 +3035,9 @@ static void mptcp_worker(struct work_struct *work)
 	if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags))
 		__mptcp_retrans(sk);
 
+	if (test_and_clear_bit(MPTCP_WORK_READ_COMPLETE, &msk->flags))
+		__mptcp_read_complete(sk);
+
 	fail_tout = msk->first ? READ_ONCE(mptcp_subflow_ctx(msk->first)->fail_tout) : 0;
 	if (fail_tout && time_after(jiffies, fail_tout))
 		mptcp_mp_fail_no_response(msk);
@@ -4381,9 +4393,6 @@ static struct sk_buff *mptcp_recv_skb(struct sock *sk, u32 *off)
 	struct sk_buff *skb;
 	u32 offset;
 
-	if (!list_empty(&msk->backlog_list))
-		mptcp_move_skbs(sk);
-
 	while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) {
 		offset = MPTCP_SKB_CB(skb)->offset;
 		if (offset < skb->len) {
@@ -4395,10 +4404,7 @@ static struct sk_buff *mptcp_recv_skb(struct sock *sk, u32 *off)
 	return NULL;
 }
 
-/*
- * Note:
- *	- It is assumed that the socket was locked by the caller.
- */
+/* Can be invoked in BH scope */
 static int __mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
 			     sk_read_actor_t recv_actor, bool noack)
 {
@@ -4441,11 +4447,14 @@ static int __mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
 	if (noack)
 		goto out;
 
-	mptcp_rcv_space_adjust(msk, copied);
-
+	/* The backlog flushing is only needed when some data is actually
+	 * moved and will take place in the workers's release callback.
+	 */
 	if (copied > 0) {
 		mptcp_recv_skb(sk, &offset);
-		mptcp_cleanup_rbuf(msk, copied);
+		msk->read_copied = copied;
+		set_bit(MPTCP_WORK_READ_COMPLETE, &msk->flags);
+		mptcp_schedule_work(sk);
 	}
 out:
 	return copied;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 4a2d40cd7b13..89902a98d383 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -115,6 +115,7 @@
 #define MPTCP_WORK_RTX		1
 #define MPTCP_FALLBACK_DONE	2
 #define MPTCP_WORK_CLOSE_SUBFLOW 3
+#define MPTCP_WORK_READ_COMPLETE 4
 
 /* MPTCP socket release cb flags */
 #define MPTCP_PUSH_PENDING	1
@@ -305,6 +306,7 @@ struct mptcp_sock {
 	u32		last_data_sent;
 	u32		last_data_recv;
 	u32		last_ack_recv;
+	int		read_copied;
 	unsigned long	timer_ival;
 	u32		token;
 	unsigned long	flags;


  reply	other threads:[~2026-07-29  8:55 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27 11:29 [PATCH mptcp-next 0/6] Reduce the differences between TCP and MPTCP for TLS usage Geliang Tang
2026-07-27 11:29 ` [PATCH mptcp-next 1/6] mptcp: drop the mptcp_ooo_try_coalesce() helper Geliang Tang
2026-07-27 11:29 ` [PATCH mptcp-next 2/6] mptcp: drop the cant_coalesce CB field Geliang Tang
2026-07-27 11:29 ` [PATCH mptcp-next 3/6] mptcp: remove CB offset field Geliang Tang
2026-07-30  1:32   ` Geliang Tang
2026-07-27 11:29 ` [PATCH mptcp-next 4/6] mptcp: sync mptcp skb cb layout with tcp one Geliang Tang
2026-07-27 11:29 ` [PATCH mptcp-next 5/6] mptcp: trim the duplicated skb head at receive enqueue Geliang Tang
2026-07-29  8:08   ` Paolo Abeni
2026-07-30  1:15     ` Geliang Tang
2026-07-30 15:00       ` Paolo Abeni
2026-07-27 11:29 ` [PATCH mptcp-next 6/6] mptcp: defer sk_data_ready to the worker Geliang Tang
2026-07-29  8:55   ` Paolo Abeni [this message]
2026-07-30  0:57     ` Geliang Tang
2026-07-30 15:18       ` Paolo Abeni
2026-07-27 12:37 ` [PATCH mptcp-next 0/6] Reduce the differences between TCP and MPTCP for TLS usage MPTCP CI

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4fade36e-9dd5-4c53-8cb3-e07c66b387b5@redhat.com \
    --to=pabeni@redhat.com \
    --cc=geliang@kernel.org \
    --cc=mptcp@lists.linux.dev \
    --cc=tanggeliang@kylinos.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.