From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: bpf@vger.kernel.org, john.fastabend@gmail.com, jakub@cloudflare.com
Cc: Jiayuan Chen <jiayuan.chen@linux.dev>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
Kuniyuki Iwashima <kuniyu@google.com>,
Willem de Bruijn <willemb@google.com>,
David Ahern <dsahern@kernel.org>,
Neal Cardwell <ncardwell@google.com>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <martin.lau@linux.dev>,
Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
KP Singh <kpsingh@kernel.org>,
Stanislav Fomichev <sdf@fomichev.me>, Hao Luo <haoluo@google.com>,
Jiri Olsa <jolsa@kernel.org>, Shuah Khan <shuah@kernel.org>,
Jiapeng Chong <jiapeng.chong@linux.alibaba.com>,
Ihor Solodrai <ihor.solodrai@linux.dev>,
Michal Luczaj <mhal@rbox.co>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: [PATCH bpf-next v1 6/7] selftests/bpf: add splice_read tests for sockmap
Date: Wed, 4 Mar 2026 14:33:57 +0800 [thread overview]
Message-ID: <20260304063643.14581-7-jiayuan.chen@linux.dev> (raw)
In-Reply-To: <20260304063643.14581-1-jiayuan.chen@linux.dev>
Add splice_read coverage to sockmap_basic and sockmap_strp selftests.
Each test suite now runs twice: once with normal recv_timeout() and
once with splice-based reads, verifying that data read via splice(2)
through a pipe produces identical results.
A recv_timeout_with_splice() helper is added to sockmap_helpers.h
that creates a temporary pipe, splices data from the socket into
the pipe, then reads from the pipe into the user buffer. MSG_PEEK
calls fall back to native recv since splice does not support peek.
Non-TCP sockets also fall back to native recv.
The splice subtests are distinguished by appending " splice" to
each subtest name via a test__start_subtest macro override.
./test_progs -a sockmap_*
...
Summary: 5/830 PASSED, 0 SKIPPED, 0 FAILED
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
.../selftests/bpf/prog_tests/sockmap_basic.c | 28 ++++++++-
.../bpf/prog_tests/sockmap_helpers.h | 62 +++++++++++++++++++
.../selftests/bpf/prog_tests/sockmap_strp.c | 28 ++++++++-
3 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
index dd3c757859f6..ea0b49ec9a93 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
@@ -18,6 +18,23 @@
#include "sockmap_helpers.h"
+static bool use_splice;
+
+static bool __start_subtest(const char *name)
+{
+ if (!use_splice)
+ return (test__start_subtest)(name);
+
+ char buf[MAX_TEST_NAME];
+
+ snprintf(buf, sizeof(buf), "%s splice", name);
+ return (test__start_subtest)(buf);
+}
+
+#define test__start_subtest(name) __start_subtest(name)
+#define recv_timeout(fd, buf, len, flags, timeout) \
+ recv_timeout_with_splice(fd, buf, len, flags, timeout, use_splice)
+
#define TCP_REPAIR 19 /* TCP sock is under repair right now */
#define TCP_REPAIR_ON 1
@@ -1314,7 +1331,7 @@ static void test_sockmap_multi_channels(int sotype)
test_sockmap_pass_prog__destroy(skel);
}
-void test_sockmap_basic(void)
+static void __test_sockmap_basic(void)
{
if (test__start_subtest("sockmap create_update_free"))
test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKMAP);
@@ -1391,3 +1408,12 @@ void test_sockmap_basic(void)
if (test__start_subtest("sockmap udp multi channels"))
test_sockmap_multi_channels(SOCK_DGRAM);
}
+
+void test_sockmap_basic(void)
+{
+ use_splice = false;
+ __test_sockmap_basic();
+
+ use_splice = true;
+ __test_sockmap_basic();
+}
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h
index d815efac52fd..1f0da657243f 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h
+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h
@@ -80,4 +80,66 @@ static inline int add_to_sockmap(int mapfd, int fd1, int fd2)
return xbpf_map_update_elem(mapfd, &u32(1), &u64(fd2), BPF_NOEXIST);
}
+static inline ssize_t recv_timeout_with_splice(int fd, void *buf, size_t len,
+ int flags,
+ unsigned int timeout_sec,
+ bool do_splice)
+{
+ ssize_t total = 0;
+ int pipefd[2];
+ int fl;
+
+ int sotype, protocol;
+ socklen_t optlen = sizeof(sotype);
+
+ if (!do_splice || (flags & MSG_PEEK) ||
+ getsockopt(fd, SOL_SOCKET, SO_TYPE, &sotype, &optlen) ||
+ sotype != SOCK_STREAM ||
+ getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &optlen) ||
+ protocol != IPPROTO_TCP)
+ return recv_timeout(fd, buf, len, flags, timeout_sec);
+
+ if (poll_read(fd, timeout_sec))
+ return -1;
+
+ if (pipe(pipefd) < 0)
+ return -1;
+
+ /*
+ * tcp_splice_read() only checks sock->file->f_flags for
+ * O_NONBLOCK, ignoring SPLICE_F_NONBLOCK for the socket
+ * side timeout. Set O_NONBLOCK on the fd so the loop won't
+ * block forever when no more data is available.
+ */
+ fl = fcntl(fd, F_GETFL);
+ fcntl(fd, F_SETFL, fl | O_NONBLOCK);
+
+ /*
+ * Pipe has limited buffer slots (default 16), so a single
+ * splice may not transfer all requested bytes. Loop until
+ * we've read enough or no more data is available.
+ */
+ while (total < (ssize_t)len) {
+ ssize_t spliced, n;
+
+ spliced = splice(fd, NULL, pipefd[1], NULL, len - total,
+ SPLICE_F_NONBLOCK);
+ if (spliced <= 0)
+ break;
+
+ n = read(pipefd[0], buf + total, spliced);
+ if (n <= 0)
+ break;
+
+ total += n;
+ }
+
+ fcntl(fd, F_SETFL, fl);
+
+ close(pipefd[0]);
+ close(pipefd[1]);
+
+ return total > 0 ? total : -1;
+}
+
#endif // __SOCKMAP_HELPERS__
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_strp.c b/tools/testing/selftests/bpf/prog_tests/sockmap_strp.c
index 621b3b71888e..2226399eee0d 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockmap_strp.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_strp.c
@@ -6,6 +6,23 @@
#include "test_skmsg_load_helpers.skel.h"
#include "test_sockmap_strp.skel.h"
+static bool use_splice;
+
+static bool __start_subtest(const char *name)
+{
+ if (!use_splice)
+ return (test__start_subtest)(name);
+
+ char buf[MAX_TEST_NAME];
+
+ snprintf(buf, sizeof(buf), "%s splice", name);
+ return (test__start_subtest)(buf);
+}
+
+#define test__start_subtest(name) __start_subtest(name)
+#define recv_timeout(fd, buf, len, flags, timeout) \
+ recv_timeout_with_splice(fd, buf, len, flags, timeout, use_splice)
+
#define STRP_PKT_HEAD_LEN 4
#define STRP_PKT_BODY_LEN 6
#define STRP_PKT_FULL_LEN (STRP_PKT_HEAD_LEN + STRP_PKT_BODY_LEN)
@@ -431,7 +448,7 @@ static void test_sockmap_strp_verdict(int family, int sotype)
test_sockmap_strp__destroy(strp);
}
-void test_sockmap_strp(void)
+static void __test_sockmap_strp(void)
{
if (test__start_subtest("sockmap strp tcp pass"))
test_sockmap_strp_pass(AF_INET, SOCK_STREAM, false);
@@ -452,3 +469,12 @@ void test_sockmap_strp(void)
if (test__start_subtest("sockmap strp tcp dispatch"))
test_sockmap_strp_dispatch_pkt(AF_INET, SOCK_STREAM);
}
+
+void test_sockmap_strp(void)
+{
+ use_splice = false;
+ __test_sockmap_strp();
+
+ use_splice = true;
+ __test_sockmap_strp();
+}
--
2.43.0
next prev parent reply other threads:[~2026-03-04 6:39 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-04 6:33 [PATCH bpf-next v1 0/7] bpf/sockmap: add splice support for tcp_bpf Jiayuan Chen
2026-03-04 6:33 ` [PATCH bpf-next v1 1/7] net: add splice_read to struct proto and set it in tcp_prot/tcpv6_prot Jiayuan Chen
2026-03-04 6:33 ` [PATCH bpf-next v1 2/7] inet: add inet_splice_read() and use it in inet_stream_ops/inet6_stream_ops Jiayuan Chen
2026-03-04 6:33 ` [PATCH bpf-next v1 3/7] tcp_bpf: refactor recvmsg with read actor abstraction Jiayuan Chen
2026-03-04 7:14 ` bot+bpf-ci
2026-03-04 6:33 ` [PATCH bpf-next v1 4/7] tcp_bpf: add splice_read support for sockmap Jiayuan Chen
2026-03-04 7:27 ` bot+bpf-ci
2026-03-04 6:33 ` [PATCH bpf-next v1 5/7] tcp_bpf: optimize splice_read with zero-copy for non-slab pages Jiayuan Chen
2026-03-04 6:33 ` Jiayuan Chen [this message]
2026-03-06 17:25 ` [PATCH bpf-next v1 6/7] selftests/bpf: add splice_read tests for sockmap Mykyta Yatsenko
2026-03-04 6:33 ` [PATCH bpf-next v1 7/7] selftests/bpf: add splice option to sockmap benchmark Jiayuan Chen
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=20260304063643.14581-7-jiayuan.chen@linux.dev \
--to=jiayuan.chen@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=eddyz87@gmail.com \
--cc=edumazet@google.com \
--cc=haoluo@google.com \
--cc=horms@kernel.org \
--cc=ihor.solodrai@linux.dev \
--cc=jakub@cloudflare.com \
--cc=jiapeng.chong@linux.alibaba.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=mhal@rbox.co \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sdf@fomichev.me \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=willemb@google.com \
--cc=yonghong.song@linux.dev \
/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.