All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.