* [PATCH mptcp-next v15 0/6] implement mptcp read_sock
@ 2025-12-06 12:33 Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 1/6] mptcp: add eat_recv_skb helper Geliang Tang
` (9 more replies)
0 siblings, 10 replies; 17+ messages in thread
From: Geliang Tang @ 2025-12-06 12:33 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
v15:
- Patch 2, remove the maximum length limit as Mat suggested.
- Move tcp_recv_should_stop() helper out of the series as Mat
suggested.
v14:
- Patch 2, new helper __mptcp_read_sock() with noack parameter,
this makes it more similar to __tcp_read_sock() and also prepares
for the use of mptcp_read_sock_noack() in MPTCP KTLS support. Also
invoke msk_owned_by_me() in it to make sure socket was locked.
- Patch 5, export tcp_splice_data_recv() as Paolo suggested in v7.
- Patch 6, drop mptcp_splice_data_recv().
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1763974740.git.tanggeliang@kylinos.cn/
v13:
- rebase on "mptcp: introduce backlog processing" v6
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1761198660.git.geliang@kernel.org/
v12:
- rebase on "mptcp: receive path improvement" 1-7.
- some cleanups.
v11:
- drop "tcp: drop release and lock again in splice_read", and add this
release and lock again in mptcp_splice_read too. (Thanks Mat, I didn't
understand the intent of this code before.)
- call mptcp_rps_record_subflows() in mptcp_splice_read as Mat
suggested.
v10:
- add an offset parameter for mptcp_recv_skb and make it more like
tcp_recv_skb.
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1756780274.git.tanggeliang@kylinos.cn/
v9:
- merge the squash-to patches.
- a new patch "drop release and lock again in splice_read".
- Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1752399660.git.tanggeliang@kylinos.cn/
v8:
- export struct tcp_splice_state and tcp_splice_data_recv() in net/tcp.h.
- add a new helper mptcp_recv_should_stop.
- add mptcp_connect_splice.sh.
- update commit logs.
v7:
- only patch 1 and patch 2 changed.
- add a new helper mptcp_eat_recv_skb.
- invoke skb_peek in mptcp_recv_skb().
- use while ((skb = mptcp_recv_skb(sk)) != NULL) instead of
skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp).
v6:
- address Paolo's comments for v4, v5 (thanks)
v5:
- extract the common code of __mptcp_recvmsg_mskq() and mptcp_read_sock()
into a new helper __mptcp_recvmsg_desc() to reduce duplication code.
v4:
- v3 doesn't work for MPTCP fallback tests in mptcp_connect.sh, this
set fix it.
- invoke __mptcp_move_skbs in mptcp_read_sock.
- use INDIRECT_CALL_INET_1 in __tcp_splice_read.
v3:
- merge the two squash-to patches.
- use sk->sk_rcvbuf instead of INT_MAX as the max len in
mptcp_read_sock().
- add splice io mode for mptcp_connect and drop mptcp_splice.c test.
- the splice test for packetdrill is also added here:
https://github.com/multipath-tcp/packetdrill/pull/162
v2:
- set splice_read of mptcp
- add a splice selftest.
I have good news! I recently added MPTCP support to "NVME over TCP".
And my RFC patches are under review by NVME maintainer Hannes.
Replacing "NVME over TCP" with MPTCP is very simple. I used IPPROTO_MPTCP
instead of IPPROTO_TCP to create MPTCP sockets on both target and host
sides, these sockets are created in Kernel space.
nvmet_tcp_add_port:
ret = sock_create(port->addr.ss_family, SOCK_STREAM,
IPPROTO_MPTCP, &port->sock);
nvme_tcp_alloc_queue:
ret = sock_create_kern(current->nsproxy->net_ns,
ctrl->addr.ss_family, SOCK_STREAM,
IPPROTO_MPTCP, &queue->sock);
nvme_tcp_try_recv() needs to call .read_sock interface of struct
proto_ops, but it is not implemented in MPTCP. So I implemented it
with reference to __mptcp_recvmsg_mskq().
Since the NVME part patches are still under reviewing, I only send the
MPTCP part patches in this set to MPTCP ML for your opinions.
Geliang Tang (6):
mptcp: add eat_recv_skb helper
mptcp: implement .read_sock
tcp: export tcp_splice_state
mptcp: implement .splice_read
selftests: mptcp: add splice io mode
selftests: mptcp: connect: cover splice mode
include/net/tcp.h | 11 +
net/ipv4/tcp.c | 13 +-
net/mptcp/protocol.c | 215 +++++++++++++++++-
tools/testing/selftests/net/mptcp/Makefile | 1 +
.../selftests/net/mptcp/mptcp_connect.c | 63 ++++-
.../net/mptcp/mptcp_connect_splice.sh | 5 +
6 files changed, 289 insertions(+), 19 deletions(-)
create mode 100755 tools/testing/selftests/net/mptcp/mptcp_connect_splice.sh
--
2.51.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH mptcp-next v15 1/6] mptcp: add eat_recv_skb helper
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
@ 2025-12-06 12:33 ` Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 2/6] mptcp: implement .read_sock Geliang Tang
` (8 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Geliang Tang @ 2025-12-06 12:33 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch extracts the free skb related code in __mptcp_recvmsg_mskq()
into a new helper mptcp_eat_recv_skb().
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/protocol.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 23c4db484861..9d67c751b7a9 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2017,6 +2017,17 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
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)
+{
+ /* avoid the indirect call, we know the destructor is sock_rfree */
+ skb->destructor = NULL;
+ skb->sk = NULL;
+ atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
+ sk_mem_uncharge(sk, skb->truesize);
+ __skb_unlink(skb, &sk->sk_receive_queue);
+ skb_attempt_defer_free(skb);
+}
+
static int __mptcp_recvmsg_mskq(struct sock *sk, struct msghdr *msg,
size_t len, int flags, int copied_total,
struct scm_timestamping_internal *tss,
@@ -2071,13 +2082,7 @@ static int __mptcp_recvmsg_mskq(struct sock *sk, struct msghdr *msg,
break;
}
- /* avoid the indirect call, we know the destructor is sock_rfree */
- skb->destructor = NULL;
- skb->sk = NULL;
- atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
- sk_mem_uncharge(sk, skb->truesize);
- __skb_unlink(skb, &sk->sk_receive_queue);
- skb_attempt_defer_free(skb);
+ mptcp_eat_recv_skb(sk, skb);
}
if (copied >= len)
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH mptcp-next v15 2/6] mptcp: implement .read_sock
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 1/6] mptcp: add eat_recv_skb helper Geliang Tang
@ 2025-12-06 12:33 ` Geliang Tang
2025-12-11 18:22 ` Matthieu Baerts
2025-12-06 12:33 ` [PATCH mptcp-next v15 3/6] tcp: export tcp_splice_state Geliang Tang
` (7 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2025-12-06 12:33 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Hannes Reinecke
From: Geliang Tang <tanggeliang@kylinos.cn>
nvme_tcp_try_recv() needs to call .read_sock interface of struct
proto_ops, but it's not implemented in MPTCP.
This patch implements it with reference to __tcp_read_sock() and
__mptcp_recvmsg_mskq().
Corresponding to tcp_recv_skb(), a new helper for MPTCP named
mptcp_recv_skb() is added to peek a skb from sk->sk_receive_queue.
Compared with __mptcp_recvmsg_mskq(), mptcp_read_sock() uses
sk->sk_rcvbuf as the max read length. The LISTEN status is checked
before the while loop, and mptcp_recv_skb() and mptcp_cleanup_rbuf()
are invoked after the loop. In the loop, all flags checks for
__mptcp_recvmsg_mskq() are removed.
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/protocol.c | 82 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 9d67c751b7a9..01d602f0d556 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -4322,6 +4322,86 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
return mask;
}
+static struct sk_buff *mptcp_recv_skb(struct sock *sk, u32 *off)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ 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) {
+ *off = offset;
+ return skb;
+ }
+ mptcp_eat_recv_skb(sk, skb);
+ }
+ return NULL;
+}
+
+/*
+ * Note:
+ * - It is assumed that the socket was locked by the caller.
+ */
+static int __mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
+ sk_read_actor_t recv_actor, bool noack)
+{
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ struct sk_buff *skb;
+ int copied = 0;
+ u32 offset;
+
+ msk_owned_by_me(msk);
+
+ if (sk->sk_state == TCP_LISTEN)
+ return -ENOTCONN;
+ while ((skb = mptcp_recv_skb(sk, &offset)) != NULL) {
+ u32 data_len = skb->len - offset;
+ int count;
+ u32 size;
+
+ size = min_t(size_t, data_len, INT_MAX);
+ count = recv_actor(desc, skb, offset, size);
+ if (count <= 0) {
+ if (!copied)
+ copied = count;
+ break;
+ }
+
+ copied += count;
+
+ msk->bytes_consumed += count;
+ if (count < data_len) {
+ MPTCP_SKB_CB(skb)->offset += count;
+ MPTCP_SKB_CB(skb)->map_seq += count;
+ break;
+ }
+
+ mptcp_eat_recv_skb(sk, skb);
+ }
+
+ if (noack)
+ goto out;
+
+ mptcp_rcv_space_adjust(msk, copied);
+
+ if (copied > 0) {
+ mptcp_recv_skb(sk, &offset);
+ mptcp_cleanup_rbuf(msk, copied);
+ }
+out:
+ return copied;
+}
+
+static int mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
+ sk_read_actor_t recv_actor)
+{
+ return __mptcp_read_sock(sk, desc, recv_actor, false);
+}
+
static const struct proto_ops mptcp_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
@@ -4342,6 +4422,7 @@ static const struct proto_ops mptcp_stream_ops = {
.recvmsg = inet_recvmsg,
.mmap = sock_no_mmap,
.set_rcvlowat = mptcp_set_rcvlowat,
+ .read_sock = mptcp_read_sock,
};
static struct inet_protosw mptcp_protosw = {
@@ -4446,6 +4527,7 @@ static const struct proto_ops mptcp_v6_stream_ops = {
.compat_ioctl = inet6_compat_ioctl,
#endif
.set_rcvlowat = mptcp_set_rcvlowat,
+ .read_sock = mptcp_read_sock,
};
static struct proto mptcp_v6_prot;
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH mptcp-next v15 3/6] tcp: export tcp_splice_state
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 1/6] mptcp: add eat_recv_skb helper Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 2/6] mptcp: implement .read_sock Geliang Tang
@ 2025-12-06 12:33 ` Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 4/6] mptcp: implement .splice_read Geliang Tang
` (6 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Geliang Tang @ 2025-12-06 12:33 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Paolo Abeni
From: Geliang Tang <tanggeliang@kylinos.cn>
Export struct tcp_splice_state and tcp_splice_data_recv() in net/tcp.h so
that they can be used by MPTCP.
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
include/net/tcp.h | 11 +++++++++++
net/ipv4/tcp.c | 13 ++-----------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 0deb5e9dd911..f5f6119f7716 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -347,6 +347,15 @@ extern struct proto tcp_prot;
#define TCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mib.tcp_statistics, field)
#define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val)
+/*
+ * TCP splice context
+ */
+struct tcp_splice_state {
+ struct pipe_inode_info *pipe;
+ size_t len;
+ unsigned int flags;
+};
+
void tcp_tsq_work_init(void);
int tcp_v4_err(struct sk_buff *skb, u32);
@@ -378,6 +387,8 @@ void tcp_rcv_space_adjust(struct sock *sk);
int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp);
void tcp_twsk_destructor(struct sock *sk);
void tcp_twsk_purge(struct list_head *net_exit_list);
+int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
+ unsigned int offset, size_t len);
ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len,
unsigned int flags);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 313c7cf208d8..40ad9656dc9e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -318,15 +318,6 @@ EXPORT_SYMBOL(tcp_have_smc);
struct percpu_counter tcp_sockets_allocated ____cacheline_aligned_in_smp;
EXPORT_IPV6_MOD(tcp_sockets_allocated);
-/*
- * TCP splice context
- */
-struct tcp_splice_state {
- struct pipe_inode_info *pipe;
- size_t len;
- unsigned int flags;
-};
-
/*
* Pressure flag: try to collapse.
* Technical note: it is used by multiple contexts non atomically.
@@ -775,8 +766,8 @@ void tcp_push(struct sock *sk, int flags, int mss_now,
__tcp_push_pending_frames(sk, mss_now, nonagle);
}
-static int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
- unsigned int offset, size_t len)
+int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
+ unsigned int offset, size_t len)
{
struct tcp_splice_state *tss = rd_desc->arg.data;
int ret;
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH mptcp-next v15 4/6] mptcp: implement .splice_read
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
` (2 preceding siblings ...)
2025-12-06 12:33 ` [PATCH mptcp-next v15 3/6] tcp: export tcp_splice_state Geliang Tang
@ 2025-12-06 12:33 ` Geliang Tang
2026-01-30 7:19 ` Matthieu Baerts
2025-12-06 12:33 ` [PATCH mptcp-next v15 5/6] selftests: mptcp: add splice io mode Geliang Tang
` (5 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2025-12-06 12:33 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch implements .splice_read interface of mptcp struct proto_ops
as mptcp_splice_read() with reference to tcp_splice_read().
Corresponding to __tcp_splice_read(), __mptcp_splice_read() is defined,
invoking mptcp_read_sock() instead of tcp_read_sock().
mptcp_splice_read() is almost the same as tcp_splice_read(), except for
sock_rps_record_flow().
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
net/mptcp/protocol.c | 114 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 01d602f0d556..334fdb10fdf3 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -4402,6 +4402,118 @@ static int mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
return __mptcp_read_sock(sk, desc, recv_actor, false);
}
+static int __mptcp_splice_read(struct sock *sk, struct tcp_splice_state *tss)
+{
+ /* Store TCP splice context information in read_descriptor_t. */
+ read_descriptor_t rd_desc = {
+ .arg.data = tss,
+ .count = tss->len,
+ };
+
+ return mptcp_read_sock(sk, &rd_desc, tcp_splice_data_recv);
+}
+
+/**
+ * mptcp_splice_read - splice data from MPTCP socket to a pipe
+ * @sock: socket to splice from
+ * @ppos: position (not valid)
+ * @pipe: pipe to splice to
+ * @len: number of bytes to splice
+ * @flags: splice modifier flags
+ *
+ * Description:
+ * Will read pages from given socket and fill them into a pipe.
+ *
+ **/
+static ssize_t mptcp_splice_read(struct socket *sock, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags)
+{
+ struct tcp_splice_state tss = {
+ .pipe = pipe,
+ .len = len,
+ .flags = flags,
+ };
+ struct sock *sk = sock->sk;
+ ssize_t spliced = 0;
+ int ret = 0;
+ long timeo;
+
+ /*
+ * We can't seek on a socket input
+ */
+ if (unlikely(*ppos))
+ return -ESPIPE;
+
+ lock_sock(sk);
+
+ mptcp_rps_record_subflows(mptcp_sk(sk));
+
+ timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK);
+ while (tss.len) {
+ ret = __mptcp_splice_read(sk, &tss);
+ if (ret < 0) {
+ break;
+ } else if (!ret) {
+ if (spliced)
+ break;
+ if (sock_flag(sk, SOCK_DONE))
+ break;
+ if (sk->sk_err) {
+ ret = sock_error(sk);
+ break;
+ }
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ break;
+ if (sk->sk_state == TCP_CLOSE) {
+ /*
+ * This occurs when user tries to read
+ * from never connected socket.
+ */
+ ret = -ENOTCONN;
+ break;
+ }
+ if (!timeo) {
+ ret = -EAGAIN;
+ break;
+ }
+ /* if __mptcp_splice_read() got nothing while we have
+ * an skb in receive queue, we do not want to loop.
+ * This might happen with URG data.
+ */
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ break;
+ ret = sk_wait_data(sk, &timeo, NULL);
+ if (ret < 0)
+ break;
+ if (signal_pending(current)) {
+ ret = sock_intr_errno(timeo);
+ break;
+ }
+ continue;
+ }
+ tss.len -= ret;
+ spliced += ret;
+
+ if (!tss.len || !timeo)
+ break;
+ release_sock(sk);
+ lock_sock(sk);
+
+ if (sk->sk_err || sk->sk_state == TCP_CLOSE ||
+ (sk->sk_shutdown & RCV_SHUTDOWN) ||
+ signal_pending(current))
+ break;
+ }
+
+ release_sock(sk);
+
+ if (spliced)
+ return spliced;
+
+ return ret;
+}
+
static const struct proto_ops mptcp_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
@@ -4423,6 +4535,7 @@ static const struct proto_ops mptcp_stream_ops = {
.mmap = sock_no_mmap,
.set_rcvlowat = mptcp_set_rcvlowat,
.read_sock = mptcp_read_sock,
+ .splice_read = mptcp_splice_read,
};
static struct inet_protosw mptcp_protosw = {
@@ -4528,6 +4641,7 @@ static const struct proto_ops mptcp_v6_stream_ops = {
#endif
.set_rcvlowat = mptcp_set_rcvlowat,
.read_sock = mptcp_read_sock,
+ .splice_read = mptcp_splice_read,
};
static struct proto mptcp_v6_prot;
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH mptcp-next v15 5/6] selftests: mptcp: add splice io mode
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
` (3 preceding siblings ...)
2025-12-06 12:33 ` [PATCH mptcp-next v15 4/6] mptcp: implement .splice_read Geliang Tang
@ 2025-12-06 12:33 ` Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 6/6] selftests: mptcp: connect: cover splice mode Geliang Tang
` (4 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Geliang Tang @ 2025-12-06 12:33 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
From: Geliang Tang <tanggeliang@kylinos.cn>
This patch adds a new 'splice' io mode for mptcp_connect to test
the newly added read_sock() and splice_read() functions of MPTCP.
do_splice() efficiently transfers data directly between two file
descriptors (infd and outfd) without copying to userspace, using
Linux's splice() system call.
Usage:
./mptcp_connect.sh -m splice
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_connect.c | 63 ++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
index 404a77bf366a..b82df82e0594 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
@@ -51,6 +51,7 @@ enum cfg_mode {
CFG_MODE_POLL,
CFG_MODE_MMAP,
CFG_MODE_SENDFILE,
+ CFG_MODE_SPLICE,
};
enum cfg_peek {
@@ -123,7 +124,7 @@ static void die_usage(void)
fprintf(stderr, "\t-j -- add additional sleep at connection start and tear down "
"-- for MPJ tests\n");
fprintf(stderr, "\t-l -- listens mode, accepts incoming connection\n");
- fprintf(stderr, "\t-m [poll|mmap|sendfile] -- use poll(default)/mmap+write/sendfile\n");
+ fprintf(stderr, "\t-m [poll|mmap|sendfile|splice] -- use poll(default)/mmap+write/sendfile/splice\n");
fprintf(stderr, "\t-M mark -- set socket packet mark\n");
fprintf(stderr, "\t-o option -- test sockopt <option>\n");
fprintf(stderr, "\t-p num -- use port num\n");
@@ -934,6 +935,55 @@ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
return err;
}
+static int do_splice(const int infd, const int outfd, const size_t len,
+ struct wstate *winfo)
+{
+ int pipefd[2];
+ ssize_t bytes;
+ int err;
+
+ err = pipe(pipefd);
+ if (err)
+ return err;
+
+ while ((bytes = splice(infd, NULL, pipefd[1], NULL,
+ len - winfo->total_len,
+ SPLICE_F_MOVE | SPLICE_F_MORE)) > 0) {
+ splice(pipefd[0], NULL, outfd, NULL, bytes,
+ SPLICE_F_MOVE | SPLICE_F_MORE);
+ }
+
+ close(pipefd[0]);
+ close(pipefd[1]);
+
+ return 0;
+}
+
+static int copyfd_io_splice(int infd, int peerfd, int outfd, unsigned int size,
+ bool *in_closed_after_out, struct wstate *winfo)
+{
+ int err;
+
+ if (listen_mode) {
+ err = do_splice(peerfd, outfd, size, winfo);
+ if (err)
+ return err;
+
+ err = do_splice(infd, peerfd, size, winfo);
+ } else {
+ err = do_splice(infd, peerfd, size, winfo);
+ if (err)
+ return err;
+
+ shut_wr(peerfd);
+
+ err = do_splice(peerfd, outfd, size, winfo);
+ *in_closed_after_out = true;
+ }
+
+ return err;
+}
+
static int copyfd_io(int infd, int peerfd, int outfd, bool close_peerfd, struct wstate *winfo)
{
bool in_closed_after_out = false;
@@ -966,6 +1016,14 @@ static int copyfd_io(int infd, int peerfd, int outfd, bool close_peerfd, struct
&in_closed_after_out, winfo);
break;
+ case CFG_MODE_SPLICE:
+ file_size = get_infd_size(infd);
+ if (file_size < 0)
+ return file_size;
+ ret = copyfd_io_splice(infd, peerfd, outfd, file_size,
+ &in_closed_after_out, winfo);
+ break;
+
default:
fprintf(stderr, "Invalid mode %d\n", cfg_mode);
@@ -1379,12 +1437,15 @@ int parse_mode(const char *mode)
return CFG_MODE_MMAP;
if (!strcasecmp(mode, "sendfile"))
return CFG_MODE_SENDFILE;
+ if (!strcasecmp(mode, "splice"))
+ return CFG_MODE_SPLICE;
fprintf(stderr, "Unknown test mode: %s\n", mode);
fprintf(stderr, "Supported modes are:\n");
fprintf(stderr, "\t\t\"poll\" - interleaved read/write using poll()\n");
fprintf(stderr, "\t\t\"mmap\" - send entire input file (mmap+write), then read response (-l will read input first)\n");
fprintf(stderr, "\t\t\"sendfile\" - send entire input file (sendfile), then read response (-l will read input first)\n");
+ fprintf(stderr, "\t\t\"splice\" - send entire input file (splice), then read response (-l will read input first)\n");
die_usage();
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH mptcp-next v15 6/6] selftests: mptcp: connect: cover splice mode
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
` (4 preceding siblings ...)
2025-12-06 12:33 ` [PATCH mptcp-next v15 5/6] selftests: mptcp: add splice io mode Geliang Tang
@ 2025-12-06 12:33 ` Geliang Tang
2025-12-06 13:51 ` [PATCH mptcp-next v15 0/6] implement mptcp read_sock MPTCP CI
` (3 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Geliang Tang @ 2025-12-06 12:33 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Matthieu Baerts
From: Geliang Tang <tanggeliang@kylinos.cn>
The "splice" alternate mode for mptcp_connect.sh/.c is available now,
this patch adds mptcp_connect_splice.sh to test it in the MPTCP CI by
default.
Suggested-by: Matthieu Baerts <matttbe@kernel.org>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
tools/testing/selftests/net/mptcp/Makefile | 1 +
tools/testing/selftests/net/mptcp/mptcp_connect_splice.sh | 5 +++++
2 files changed, 6 insertions(+)
create mode 100755 tools/testing/selftests/net/mptcp/mptcp_connect_splice.sh
diff --git a/tools/testing/selftests/net/mptcp/Makefile b/tools/testing/selftests/net/mptcp/Makefile
index 15d144a25d82..30d9022119fa 100644
--- a/tools/testing/selftests/net/mptcp/Makefile
+++ b/tools/testing/selftests/net/mptcp/Makefile
@@ -10,6 +10,7 @@ TEST_PROGS := \
mptcp_connect_checksum.sh \
mptcp_connect_mmap.sh \
mptcp_connect_sendfile.sh \
+ mptcp_connect_splice.sh \
mptcp_join.sh \
mptcp_sockopt.sh \
pm_netlink.sh \
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect_splice.sh b/tools/testing/selftests/net/mptcp/mptcp_connect_splice.sh
new file mode 100755
index 000000000000..241254a966c9
--- /dev/null
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect_splice.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+MPTCP_LIB_KSFT_TEST="$(basename "${0}" .sh)" \
+ "$(dirname "${0}")/mptcp_connect.sh" -m splice "${@}"
--
2.51.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH mptcp-next v15 0/6] implement mptcp read_sock
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
` (5 preceding siblings ...)
2025-12-06 12:33 ` [PATCH mptcp-next v15 6/6] selftests: mptcp: connect: cover splice mode Geliang Tang
@ 2025-12-06 13:51 ` MPTCP CI
2025-12-06 17:01 ` MPTCP CI
` (2 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: MPTCP CI @ 2025-12-06 13:51 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): Critical: Global Timeout ❌
- 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): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/19988767626
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/4bf455dd3ee0
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1031070
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] 17+ messages in thread
* Re: [PATCH mptcp-next v15 0/6] implement mptcp read_sock
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
` (6 preceding siblings ...)
2025-12-06 13:51 ` [PATCH mptcp-next v15 0/6] implement mptcp read_sock MPTCP CI
@ 2025-12-06 17:01 ` MPTCP CI
2025-12-10 1:28 ` Mat Martineau
2025-12-11 18:26 ` Matthieu Baerts
9 siblings, 0 replies; 17+ messages in thread
From: MPTCP CI @ 2025-12-06 17:01 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): Unstable: 1 failed test(s): selftest_simult_flows 🔴
- 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): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/19988767626
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/4bf455dd3ee0
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1031070
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] 17+ messages in thread
* Re: [PATCH mptcp-next v15 0/6] implement mptcp read_sock
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
` (7 preceding siblings ...)
2025-12-06 17:01 ` MPTCP CI
@ 2025-12-10 1:28 ` Mat Martineau
2025-12-10 1:30 ` Mat Martineau
2025-12-11 18:26 ` Matthieu Baerts
9 siblings, 1 reply; 17+ messages in thread
From: Mat Martineau @ 2025-12-10 1:28 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp, Geliang Tang
On Sat, 6 Dec 2025, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
>
> v15:
> - Patch 2, remove the maximum length limit as Mat suggested.
> - Move tcp_recv_should_stop() helper out of the series as Mat
> suggested.
Thanks Geliang, series LGTM:
Reviewed-by: Mat Martineau <martineau@kernel.org>
(except patch 2 which I will ack separately)
>
> v14:
> - Patch 2, new helper __mptcp_read_sock() with noack parameter,
> this makes it more similar to __tcp_read_sock() and also prepares
> for the use of mptcp_read_sock_noack() in MPTCP KTLS support. Also
> invoke msk_owned_by_me() in it to make sure socket was locked.
> - Patch 5, export tcp_splice_data_recv() as Paolo suggested in v7.
> - Patch 6, drop mptcp_splice_data_recv().
> - Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1763974740.git.tanggeliang@kylinos.cn/
>
> v13:
> - rebase on "mptcp: introduce backlog processing" v6
> - Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1761198660.git.geliang@kernel.org/
>
> v12:
> - rebase on "mptcp: receive path improvement" 1-7.
> - some cleanups.
>
> v11:
> - drop "tcp: drop release and lock again in splice_read", and add this
> release and lock again in mptcp_splice_read too. (Thanks Mat, I didn't
> understand the intent of this code before.)
> - call mptcp_rps_record_subflows() in mptcp_splice_read as Mat
> suggested.
>
> v10:
> - add an offset parameter for mptcp_recv_skb and make it more like
> tcp_recv_skb.
> - Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1756780274.git.tanggeliang@kylinos.cn/
>
> v9:
> - merge the squash-to patches.
> - a new patch "drop release and lock again in splice_read".
> - Link: https://patchwork.kernel.org/project/mptcp/cover/cover.1752399660.git.tanggeliang@kylinos.cn/
>
> v8:
> - export struct tcp_splice_state and tcp_splice_data_recv() in net/tcp.h.
> - add a new helper mptcp_recv_should_stop.
> - add mptcp_connect_splice.sh.
> - update commit logs.
>
> v7:
> - only patch 1 and patch 2 changed.
> - add a new helper mptcp_eat_recv_skb.
> - invoke skb_peek in mptcp_recv_skb().
> - use while ((skb = mptcp_recv_skb(sk)) != NULL) instead of
> skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp).
>
> v6:
> - address Paolo's comments for v4, v5 (thanks)
>
> v5:
> - extract the common code of __mptcp_recvmsg_mskq() and mptcp_read_sock()
> into a new helper __mptcp_recvmsg_desc() to reduce duplication code.
>
> v4:
> - v3 doesn't work for MPTCP fallback tests in mptcp_connect.sh, this
> set fix it.
> - invoke __mptcp_move_skbs in mptcp_read_sock.
> - use INDIRECT_CALL_INET_1 in __tcp_splice_read.
>
> v3:
> - merge the two squash-to patches.
> - use sk->sk_rcvbuf instead of INT_MAX as the max len in
> mptcp_read_sock().
> - add splice io mode for mptcp_connect and drop mptcp_splice.c test.
> - the splice test for packetdrill is also added here:
> https://github.com/multipath-tcp/packetdrill/pull/162
>
> v2:
> - set splice_read of mptcp
> - add a splice selftest.
>
> I have good news! I recently added MPTCP support to "NVME over TCP".
> And my RFC patches are under review by NVME maintainer Hannes.
>
> Replacing "NVME over TCP" with MPTCP is very simple. I used IPPROTO_MPTCP
> instead of IPPROTO_TCP to create MPTCP sockets on both target and host
> sides, these sockets are created in Kernel space.
>
> nvmet_tcp_add_port:
>
> ret = sock_create(port->addr.ss_family, SOCK_STREAM,
> IPPROTO_MPTCP, &port->sock);
>
> nvme_tcp_alloc_queue:
>
> ret = sock_create_kern(current->nsproxy->net_ns,
> ctrl->addr.ss_family, SOCK_STREAM,
> IPPROTO_MPTCP, &queue->sock);
>
> nvme_tcp_try_recv() needs to call .read_sock interface of struct
> proto_ops, but it is not implemented in MPTCP. So I implemented it
> with reference to __mptcp_recvmsg_mskq().
>
> Since the NVME part patches are still under reviewing, I only send the
> MPTCP part patches in this set to MPTCP ML for your opinions.
>
> Geliang Tang (6):
> mptcp: add eat_recv_skb helper
> mptcp: implement .read_sock
> tcp: export tcp_splice_state
> mptcp: implement .splice_read
> selftests: mptcp: add splice io mode
> selftests: mptcp: connect: cover splice mode
>
> include/net/tcp.h | 11 +
> net/ipv4/tcp.c | 13 +-
> net/mptcp/protocol.c | 215 +++++++++++++++++-
> tools/testing/selftests/net/mptcp/Makefile | 1 +
> .../selftests/net/mptcp/mptcp_connect.c | 63 ++++-
> .../net/mptcp/mptcp_connect_splice.sh | 5 +
> 6 files changed, 289 insertions(+), 19 deletions(-)
> create mode 100755 tools/testing/selftests/net/mptcp/mptcp_connect_splice.sh
>
> --
> 2.51.0
>
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH mptcp-next v15 0/6] implement mptcp read_sock
2025-12-10 1:28 ` Mat Martineau
@ 2025-12-10 1:30 ` Mat Martineau
0 siblings, 0 replies; 17+ messages in thread
From: Mat Martineau @ 2025-12-10 1:30 UTC (permalink / raw)
To: Geliang Tang, Matthieu Baerts; +Cc: mptcp, Geliang Tang
On Tue, 9 Dec 2025, Mat Martineau wrote:
> On Sat, 6 Dec 2025, Geliang Tang wrote:
>
>> From: Geliang Tang <tanggeliang@kylinos.cn>
>>
>> v15:
>> - Patch 2, remove the maximum length limit as Mat suggested.
>> - Move tcp_recv_should_stop() helper out of the series as Mat
>> suggested.
>
> Thanks Geliang, series LGTM:
>
> Reviewed-by: Mat Martineau <martineau@kernel.org>
>
> (except patch 2 which I will ack separately)
Actually, patch 3 :)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH mptcp-next v15 2/6] mptcp: implement .read_sock
2025-12-06 12:33 ` [PATCH mptcp-next v15 2/6] mptcp: implement .read_sock Geliang Tang
@ 2025-12-11 18:22 ` Matthieu Baerts
2025-12-12 9:11 ` Geliang Tang
0 siblings, 1 reply; 17+ messages in thread
From: Matthieu Baerts @ 2025-12-11 18:22 UTC (permalink / raw)
To: Geliang Tang; +Cc: Geliang Tang, Hannes Reinecke, mptcp
Hi Geliang,
Thank you for working on that!
On 06/12/2025 13:33, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
>
> nvme_tcp_try_recv() needs to call .read_sock interface of struct
> proto_ops, but it's not implemented in MPTCP.
>
> This patch implements it with reference to __tcp_read_sock() and
> __mptcp_recvmsg_mskq().
>
> Corresponding to tcp_recv_skb(), a new helper for MPTCP named
> mptcp_recv_skb() is added to peek a skb from sk->sk_receive_queue.
>
> Compared with __mptcp_recvmsg_mskq(), mptcp_read_sock() uses
> sk->sk_rcvbuf as the max read length. The LISTEN status is checked
> before the while loop, and mptcp_recv_skb() and mptcp_cleanup_rbuf()
> are invoked after the loop. In the loop, all flags checks for
> __mptcp_recvmsg_mskq() are removed.
(...)
> +static int mptcp_read_sock(struct sock *sk, read_descriptor_t *desc,
> + sk_read_actor_t recv_actor)
> +{
> + return __mptcp_read_sock(sk, desc, recv_actor, false);
In this series, it looks like __mptcp_read_sock() is only called here,
always with noack == false then. Will you call this helper with noack
set to true in another series?
(Maybe the extension could be introduced later, but if the next series
follows, that's fine to keep it like that.)
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH mptcp-next v15 0/6] implement mptcp read_sock
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
` (8 preceding siblings ...)
2025-12-10 1:28 ` Mat Martineau
@ 2025-12-11 18:26 ` Matthieu Baerts
9 siblings, 0 replies; 17+ messages in thread
From: Matthieu Baerts @ 2025-12-11 18:26 UTC (permalink / raw)
To: Geliang Tang, mptcp; +Cc: Geliang Tang
Hi Geliang, Mat,
On 06/12/2025 13:33, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
>
> v15:
> - Patch 2, remove the maximum length limit as Mat suggested.
> - Move tcp_recv_should_stop() helper out of the series as Mat
> suggested.
(...)
> Geliang Tang (6):
> mptcp: add eat_recv_skb helper
> mptcp: implement .read_sock
> tcp: export tcp_splice_state
> mptcp: implement .splice_read
> selftests: mptcp: add splice io mode
> selftests: mptcp: connect: cover splice mode
Thank you for this series and the reviews!
Now in our tree (I have one question on patch 2/6, but not blocking).
New patches for t/upstream:
- e78890a6ea4b: mptcp: add eat_recv_skb helper
- cd77bb397ce5: mptcp: implement .read_sock
- 5e585fdd542a: tcp: export tcp_splice_state
- f7f50269c753: tg:msg: switch Mat's RvB to Acked-by
- 95e576d9d745: mptcp: implement .splice_read
- 5c48da682a24: selftests: mptcp: add splice io mode
- 8a1663feb989: selftests: mptcp: connect: cover splice mode
- Results: ff3fd5f60460..51ec4882d220 (export)
Tests are now in progress:
- export:
https://github.com/multipath-tcp/mptcp_net-next/commit/cdae7102afdc1eeafc0fa217f76f746ffd67c561/checks
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH mptcp-next v15 2/6] mptcp: implement .read_sock
2025-12-11 18:22 ` Matthieu Baerts
@ 2025-12-12 9:11 ` Geliang Tang
0 siblings, 0 replies; 17+ messages in thread
From: Geliang Tang @ 2025-12-12 9:11 UTC (permalink / raw)
To: Matthieu Baerts; +Cc: Geliang Tang, Hannes Reinecke, mptcp
Hi Matt,
On Thu, 2025-12-11 at 19:22 +0100, Matthieu Baerts wrote:
> Hi Geliang,
>
> Thank you for working on that!
>
> On 06/12/2025 13:33, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> >
> > nvme_tcp_try_recv() needs to call .read_sock interface of struct
> > proto_ops, but it's not implemented in MPTCP.
> >
> > This patch implements it with reference to __tcp_read_sock() and
> > __mptcp_recvmsg_mskq().
> >
> > Corresponding to tcp_recv_skb(), a new helper for MPTCP named
> > mptcp_recv_skb() is added to peek a skb from sk->sk_receive_queue.
> >
> > Compared with __mptcp_recvmsg_mskq(), mptcp_read_sock() uses
> > sk->sk_rcvbuf as the max read length. The LISTEN status is checked
> > before the while loop, and mptcp_recv_skb() and
> > mptcp_cleanup_rbuf()
> > are invoked after the loop. In the loop, all flags checks for
> > __mptcp_recvmsg_mskq() are removed.
>
> (...)
>
> > +static int mptcp_read_sock(struct sock *sk, read_descriptor_t
> > *desc,
> > + sk_read_actor_t recv_actor)
> > +{
> > + return __mptcp_read_sock(sk, desc, recv_actor, false);
>
> In this series, it looks like __mptcp_read_sock() is only called
> here,
> always with noack == false then. Will you call this helper with noack
> set to true in another series?
Yes, indeed. This read_sock will be called in all three series that I
am currently developing.
1. In "NVME over MPTCP" series, mptcp_read_sock() will be used, see:
consumed = sock->ops->read_sock(sk, &rd_desc, nvme_tcp_recv_skb);
in nvme_tcp_try_recv().
2. In "MPTCP sockmap support" series (issue #521),
mptcp_read_sock_noack() will be used, see:
copied = tcp_read_sock_noack(sk, desc, recv_actor, true,
&psock->copied_seq);
in tcp_bpf_strp_read_sock().
3. In "MPTCP KTLS support" series (issue #480), tcp_read_sock() is used
in tls_strp_read_copyin():
tcp_read_sock(strp->sk, &desc, tls_strp_copyin);
I originally intended to use mptcp_read_sock() here, but it would cause
a deadlock, so I had to switch to using tcp_read_sock_noack() instead.
>
> (Maybe the extension could be introduced later, but if the next
> series
> follows, that's fine to keep it like that.)
So I think it's better to keep this patch as is.
Thanks,
-Geliang
>
> Cheers,
> Matt
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH mptcp-next v15 4/6] mptcp: implement .splice_read
2025-12-06 12:33 ` [PATCH mptcp-next v15 4/6] mptcp: implement .splice_read Geliang Tang
@ 2026-01-30 7:19 ` Matthieu Baerts
2026-01-30 13:54 ` Geliang Tang
0 siblings, 1 reply; 17+ messages in thread
From: Matthieu Baerts @ 2026-01-30 7:19 UTC (permalink / raw)
To: Geliang Tang, mptcp; +Cc: Geliang Tang
Hi Geliang,
On 06/12/2025 13:33, Geliang Tang wrote:
> From: Geliang Tang <tanggeliang@kylinos.cn>
>
> This patch implements .splice_read interface of mptcp struct proto_ops
> as mptcp_splice_read() with reference to tcp_splice_read().
>
> Corresponding to __tcp_splice_read(), __mptcp_splice_read() is defined,
> invoking mptcp_read_sock() instead of tcp_read_sock().
>
> mptcp_splice_read() is almost the same as tcp_splice_read(), except for
> sock_rps_record_flow().
(...)
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 01d602f0d556..334fdb10fdf3 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
(...)
> @@ -4423,6 +4535,7 @@ static const struct proto_ops mptcp_stream_ops = {
> .mmap = sock_no_mmap,
> .set_rcvlowat = mptcp_set_rcvlowat,
> .read_sock = mptcp_read_sock,
> + .splice_read = mptcp_splice_read,
When looking at this patch in more details (after the issue with kdoc),
I was wondering: is it not needed to also implement .splice_eof, similar
to tcp_splice_eof()?
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH mptcp-next v15 4/6] mptcp: implement .splice_read
2026-01-30 7:19 ` Matthieu Baerts
@ 2026-01-30 13:54 ` Geliang Tang
2026-01-30 17:18 ` Matthieu Baerts
0 siblings, 1 reply; 17+ messages in thread
From: Geliang Tang @ 2026-01-30 13:54 UTC (permalink / raw)
To: Matthieu Baerts, mptcp; +Cc: Geliang Tang
Hi Matt,
On Fri, 2026-01-30 at 08:19 +0100, Matthieu Baerts wrote:
> Hi Geliang,
>
> On 06/12/2025 13:33, Geliang Tang wrote:
> > From: Geliang Tang <tanggeliang@kylinos.cn>
> >
> > This patch implements .splice_read interface of mptcp struct
> > proto_ops
> > as mptcp_splice_read() with reference to tcp_splice_read().
> >
> > Corresponding to __tcp_splice_read(), __mptcp_splice_read() is
> > defined,
> > invoking mptcp_read_sock() instead of tcp_read_sock().
> >
> > mptcp_splice_read() is almost the same as tcp_splice_read(), except
> > for
> > sock_rps_record_flow().
>
> (...)
>
> > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> > index 01d602f0d556..334fdb10fdf3 100644
> > --- a/net/mptcp/protocol.c
> > +++ b/net/mptcp/protocol.c
>
> (...)
>
> > @@ -4423,6 +4535,7 @@ static const struct proto_ops
> > mptcp_stream_ops = {
> > .mmap = sock_no_mmap,
> > .set_rcvlowat = mptcp_set_rcvlowat,
> > .read_sock = mptcp_read_sock,
> > + .splice_read = mptcp_splice_read,
>
> When looking at this patch in more details (after the issue with
> kdoc),
> I was wondering: is it not needed to also implement .splice_eof,
> similar
> to tcp_splice_eof()?
Thanks for the reminder, I'll try to implement mptcp_splice_eof later.
-Geliang
>
> Cheers,
> Matt
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH mptcp-next v15 4/6] mptcp: implement .splice_read
2026-01-30 13:54 ` Geliang Tang
@ 2026-01-30 17:18 ` Matthieu Baerts
0 siblings, 0 replies; 17+ messages in thread
From: Matthieu Baerts @ 2026-01-30 17:18 UTC (permalink / raw)
To: Geliang Tang, mptcp; +Cc: Geliang Tang
Hi Matt,
On 30/01/2026 14:54, Geliang Tang wrote:
> Hi Matt,
>
> On Fri, 2026-01-30 at 08:19 +0100, Matthieu Baerts wrote:
>> Hi Geliang,
>>
>> On 06/12/2025 13:33, Geliang Tang wrote:
>>> From: Geliang Tang <tanggeliang@kylinos.cn>
>>>
>>> This patch implements .splice_read interface of mptcp struct
>>> proto_ops
>>> as mptcp_splice_read() with reference to tcp_splice_read().
>>>
>>> Corresponding to __tcp_splice_read(), __mptcp_splice_read() is
>>> defined,
>>> invoking mptcp_read_sock() instead of tcp_read_sock().
>>>
>>> mptcp_splice_read() is almost the same as tcp_splice_read(), except
>>> for
>>> sock_rps_record_flow().
>>
>> (...)
>>
>>> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
>>> index 01d602f0d556..334fdb10fdf3 100644
>>> --- a/net/mptcp/protocol.c
>>> +++ b/net/mptcp/protocol.c
>>
>> (...)
>>
>>> @@ -4423,6 +4535,7 @@ static const struct proto_ops
>>> mptcp_stream_ops = {
>>> .mmap = sock_no_mmap,
>>> .set_rcvlowat = mptcp_set_rcvlowat,
>>> .read_sock = mptcp_read_sock,
>>> + .splice_read = mptcp_splice_read,
>>
>> When looking at this patch in more details (after the issue with
>> kdoc),
>> I was wondering: is it not needed to also implement .splice_eof,
>> similar
>> to tcp_splice_eof()?
>
> Thanks for the reminder, I'll try to implement mptcp_splice_eof later.
Thank you!
I didn't check (yet), but do you know when it is used and what happens
if splice is used, but this interface is not implemented on MPTCP side?
Are there issues with the current implementation?
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-01-30 17:18 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-06 12:33 [PATCH mptcp-next v15 0/6] implement mptcp read_sock Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 1/6] mptcp: add eat_recv_skb helper Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 2/6] mptcp: implement .read_sock Geliang Tang
2025-12-11 18:22 ` Matthieu Baerts
2025-12-12 9:11 ` Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 3/6] tcp: export tcp_splice_state Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 4/6] mptcp: implement .splice_read Geliang Tang
2026-01-30 7:19 ` Matthieu Baerts
2026-01-30 13:54 ` Geliang Tang
2026-01-30 17:18 ` Matthieu Baerts
2025-12-06 12:33 ` [PATCH mptcp-next v15 5/6] selftests: mptcp: add splice io mode Geliang Tang
2025-12-06 12:33 ` [PATCH mptcp-next v15 6/6] selftests: mptcp: connect: cover splice mode Geliang Tang
2025-12-06 13:51 ` [PATCH mptcp-next v15 0/6] implement mptcp read_sock MPTCP CI
2025-12-06 17:01 ` MPTCP CI
2025-12-10 1:28 ` Mat Martineau
2025-12-10 1:30 ` Mat Martineau
2025-12-11 18:26 ` Matthieu Baerts
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox