* [LTP] [PATCH] splice08: Keep calling splice() until all bytes are spliced
@ 2026-10-30 3:13 Wake Liu via ltp
2026-10-30 6:31 ` [LTP] " linuxtestproject.agent
0 siblings, 1 reply; 2+ messages in thread
From: Wake Liu via ltp @ 2026-10-30 3:13 UTC (permalink / raw)
To: ltp; +Cc: Wake Liu
splice() may transfer fewer bytes than requested, but the test fails
as soon as a single call does not splice the whole buffer.
/dev/zero and /dev/full use copy_splice_read(), which limits the
transfer to the number of pages it gets from alloc_pages_bulk(). Since
kernel commit 187ad460b841 ("mm/page_alloc: avoid page allocator
recursion with pagesets.lock held"), the bulk allocator allocates only
one page per call when page_owner is enabled. On kernels booted with
page_owner=on, every request larger than a page is therefore cut to
PAGE_SIZE bytes and the test fails:
TPASS: splice(...) returned 4096
TFAIL: Only part 4096 bytes of 5045 were spliced
A short count is valid splice() behavior, not a kernel bug, so keep
calling splice() until the whole buffer is in the pipe and fail only
if it stops making progress before that.
Signed-off-by: Wake Liu <wakel@google.com>
---
testcases/kernel/syscalls/splice/splice08.c | 27 ++++++++++++++-------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/testcases/kernel/syscalls/splice/splice08.c b/testcases/kernel/syscalls/splice/splice08.c
index bd635ee7e..2af1c88b6 100644
--- a/testcases/kernel/syscalls/splice/splice08.c
+++ b/testcases/kernel/syscalls/splice/splice08.c
@@ -23,21 +23,30 @@ static void test_splice(unsigned int bytes, int dev_fd)
{
int pipefd[2];
char buf[bytes];
- size_t i;
+ size_t i, spliced = 0;
int fail = 0;
memset(buf, 0xff, sizeof(buf));
SAFE_PIPE(pipefd);
- TST_EXP_POSITIVE(splice(dev_fd, NULL, pipefd[1], NULL, sizeof(buf), 0));
-
- if (!TST_PASS)
- goto ret;
-
- if ((size_t)TST_RET != sizeof(buf)) {
- tst_res(TFAIL, "Only part %lu bytes of %u were spliced",
- TST_RET, bytes);
+ /*
+ * splice() may transfer less than requested, e.g. with page_owner=on
+ * copy_splice_read() gets only a single page per call, so keep
+ * splicing until all bytes are in the pipe.
+ */
+ do {
+ TST_EXP_POSITIVE(splice(dev_fd, NULL, pipefd[1], NULL,
+ sizeof(buf) - spliced, 0));
+ if (!TST_PASS)
+ goto ret;
+
+ spliced += TST_RET;
+ } while (TST_RET && spliced < sizeof(buf));
+
+ if (spliced != sizeof(buf)) {
+ tst_res(TFAIL, "Only part %zu bytes of %u were spliced",
+ spliced, bytes);
goto ret;
}
--
2.56.0.307.g5fe7bd680c-goog
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-30 6:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 3:13 [LTP] [PATCH] splice08: Keep calling splice() until all bytes are spliced Wake Liu via ltp
2026-10-30 6:31 ` [LTP] " linuxtestproject.agent
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.