* [LTP] [PATCH v6 1/2] io_uring: Add test for READV and WRITEV operations
@ 2026-04-16 12:16 Sachin Sant
2026-04-16 12:16 ` [LTP] [PATCH 2/2] io_uring: remove unused io_uring_init_buffer_pattern() Sachin Sant
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Sachin Sant @ 2026-04-16 12:16 UTC (permalink / raw)
To: ltp
Add a test to validate vectored read and write operations using io_uring.
1. IORING_OP_WRITEV - Writing data using multiple buffers (scatter)
2. IORING_OP_READV - Reading data into multiple buffers (gather)
3. Data integrity verification across multiple iovecs
4. Edge cases with different iovec configurations including zero
buffer length
Additionally merge io_uring_init_buffer_pattern() into unified
init_iovec_buffers() function that supports both rotating and
simple character patterns
Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
---
V5 changes:
- Add clear_iovec_buffers() at the top of run()
- Link to v4 https://lore.kernel.org/ltp/20260416062302.15804-1-sachinp@linux.ibm.com/T/
V4 changes:
- Updated commit message to remove references to non-existent function
- Removed extra blank line before test_writev_readv()
- Link to v3 https://lore.kernel.org/ltp/20260416042531.81093-1-sachinp@linux.ibm.com/T/
V3 changes (2/3 io_uring04 only):
- 1/3 and 3/3 from the patch series already merged.
- Merged prepare_read_buffers() and clear_iovec_buffers() into
single clear_iovec_buffers() function
- Merged io_uring_init_buffer_pattern() into unified
init_iovec_buffers() function that supports both rotating and
simple character patterns
- Removed io_uring_init_buffer_pattern() from io_uring_common.h as it's
only used in io_uring04.c
- Link to V2: https://lore.kernel.org/ltp/b4653e3f-ac9b-4a24-8d3f-51677c488e8c@linux.ibm.com/T/
V2 changes:
- Use guarded buffer(including iovec) allocation
- Move setup/cleanup code from run to appropriate path
- Add a function to map the OP to the enum name
- Define and use generic cleanup functions
- Add a buffer size 0 in the middle of the iovec
- Simplify setup_io_uring_test to use common code.
- Link to V1: https://lore.kernel.org/ltp/20260320124742.75946-1-sachinp@linux.ibm.com/T/#t
Changes after RFC patch series:
- Addressed review comments
- Refactored io_uring01 test to use common code
- Removed git tags
- Link to RFC: https://lore.kernel.org/ltp/20260318110328.52031-1-sachinp@linux.ibm.com/T/#t
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/io_uring/.gitignore | 1 +
.../kernel/syscalls/io_uring/io_uring04.c | 223 ++++++++++++++++++
3 files changed, 225 insertions(+)
create mode 100644 testcases/kernel/syscalls/io_uring/io_uring04.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 5025b259f..aa7a91d97 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1901,6 +1901,7 @@ membarrier01 membarrier01
io_uring01 io_uring01
io_uring02 io_uring02
io_uring03 io_uring03
+io_uring04 io_uring04
# Tests below may cause kernel memory leak
perf_event_open03 perf_event_open03
diff --git a/testcases/kernel/syscalls/io_uring/.gitignore b/testcases/kernel/syscalls/io_uring/.gitignore
index 9382ae413..36cd24662 100644
--- a/testcases/kernel/syscalls/io_uring/.gitignore
+++ b/testcases/kernel/syscalls/io_uring/.gitignore
@@ -1,3 +1,4 @@
/io_uring01
/io_uring02
/io_uring03
+/io_uring04
diff --git a/testcases/kernel/syscalls/io_uring/io_uring04.c b/testcases/kernel/syscalls/io_uring/io_uring04.c
new file mode 100644
index 000000000..6b6bb711d
--- /dev/null
+++ b/testcases/kernel/syscalls/io_uring/io_uring04.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2026 IBM
+ * Author: Sachin Sant <sachinp@linux.ibm.com>
+ */
+/*\
+ * Test IORING_OP_READV and IORING_OP_WRITEV operations.
+ *
+ * This test validates vectored read and write operations using io_uring.
+ * It tests:
+ * 1. IORING_OP_WRITEV - Writing data using multiple buffers (scatter)
+ * 2. IORING_OP_READV - Reading data into multiple buffers (gather)
+ * 3. Data integrity verification across multiple iovecs
+ * 4. Edge cases with different iovec configurations
+ */
+
+#include "io_uring_common.h"
+
+#define TEST_FILE "io_uring_test_file"
+#define QUEUE_DEPTH 2
+#define NUM_VECS 4
+#define VEC_SIZE 1024
+#define VAR_BUF1_SIZE 512
+#define VAR_BUF2_SIZE 1024
+#define VAR_BUF3_SIZE 256
+
+static struct iovec *write_iovs, *read_iovs;
+static struct iovec *var_write_iovs, *var_read_iovs;
+static struct io_uring_submit s;
+static sigset_t sig;
+
+/*
+ * Initialize iovec buffers with pattern
+ * @iovs: array of iovec structures
+ * @nvecs: number of iovecs
+ * @base_char: base character for pattern
+ * @use_rotating: if true, use rotating pattern; if false, use simple repeat
+ */
+static void init_iovec_buffers(struct iovec *iovs, int nvecs,
+ char base_char, int use_rotating)
+{
+ int i;
+ size_t j;
+ char *buf;
+
+ for (i = 0; i < nvecs; i++) {
+ if (iovs[i].iov_len == 0)
+ continue;
+
+ buf = (char *)iovs[i].iov_base;
+ if (use_rotating) {
+ /* Each vector has a different rotating pattern */
+ for (j = 0; j < iovs[i].iov_len; j++)
+ buf[j] = base_char + i + (j % 26);
+ } else {
+ for (j = 0; j < iovs[i].iov_len; j++)
+ buf[j] = base_char + i;
+ }
+ }
+}
+
+static void clear_iovec_buffers(struct iovec *iovs, int nvecs)
+{
+ int i;
+
+ for (i = 0; i < nvecs; i++)
+ memset(iovs[i].iov_base, 0, iovs[i].iov_len);
+}
+
+static void verify_iovec_data(struct iovec *write_iovs, struct iovec *read_iovs,
+ int nvecs, const char *test_name)
+{
+ int i;
+ size_t j;
+
+ for (i = 0; i < nvecs; i++) {
+ if (write_iovs[i].iov_len != read_iovs[i].iov_len) {
+ tst_res(TFAIL, "%s: iovec %d length mismatch: write=%zu read=%zu",
+ test_name, i, write_iovs[i].iov_len, read_iovs[i].iov_len);
+ return;
+ }
+
+ if (memcmp(write_iovs[i].iov_base, read_iovs[i].iov_base,
+ write_iovs[i].iov_len) != 0) {
+ tst_res(TFAIL, "%s: data mismatch in vector %d", test_name, i);
+ for (j = 0; j < write_iovs[i].iov_len && j < 64; j++) {
+ char *wbuf = (char *)write_iovs[i].iov_base;
+ char *rbuf = (char *)read_iovs[i].iov_base;
+ if (wbuf[j] != rbuf[j]) {
+ tst_res(TINFO, "Vector %d: first mismatch at "
+ "offset %zu: wrote 0x%02x, read 0x%02x",
+ i, j, wbuf[j], rbuf[j]);
+ break;
+ }
+ }
+ return;
+ }
+ }
+
+ tst_res(TPASS, "%s: data integrity verified across %d vectors",
+ test_name, nvecs);
+}
+
+static void test_writev_readv(void)
+{
+ int fd;
+ int total_size = NUM_VECS * VEC_SIZE;
+
+ tst_res(TINFO, "Testing IORING_OP_WRITEV and IORING_OP_READV");
+
+ fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
+
+ tst_res(TINFO, "Writing %d bytes using %d vectors", total_size, NUM_VECS);
+ io_uring_do_vec_io_op(&s, fd, IORING_OP_WRITEV, write_iovs, NUM_VECS,
+ 0, total_size, &sig);
+
+ SAFE_FSYNC(fd);
+
+ tst_res(TINFO, "Reading %d bytes using %d vectors", total_size, NUM_VECS);
+ io_uring_do_vec_io_op(&s, fd, IORING_OP_READV, read_iovs, NUM_VECS,
+ 0, total_size, &sig);
+
+ verify_iovec_data(write_iovs, read_iovs, NUM_VECS, "Basic vectored I/O");
+
+ SAFE_CLOSE(fd);
+}
+
+static void test_partial_vectors(void)
+{
+ int fd;
+ int half_size = 2 * VEC_SIZE;
+
+ tst_res(TINFO, "Testing partial vector operations");
+
+ fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
+
+ /* Write first half using first 2 vectors at offset 0 */
+ io_uring_do_vec_io_op(&s, fd, IORING_OP_WRITEV, write_iovs, 2, 0,
+ half_size, &sig);
+
+ /* Write second half using next 2 vectors at offset half_size */
+ io_uring_do_vec_io_op(&s, fd, IORING_OP_WRITEV, &write_iovs[2], 2,
+ half_size, half_size, &sig);
+
+ SAFE_FSYNC(fd);
+
+ /* Read back entire file using all 4 vectors */
+ io_uring_do_vec_io_op(&s, fd, IORING_OP_READV, read_iovs, NUM_VECS, 0,
+ NUM_VECS * VEC_SIZE, &sig);
+
+ verify_iovec_data(write_iovs, read_iovs, NUM_VECS, "Partial vector I/O");
+
+ SAFE_CLOSE(fd);
+}
+
+static void test_varying_sizes(void)
+{
+ int fd;
+ int expected_size = VAR_BUF1_SIZE + VAR_BUF2_SIZE + VAR_BUF3_SIZE;
+
+ tst_res(TINFO, "Testing vectors with varying sizes including zero-length buffer");
+
+ init_iovec_buffers(var_write_iovs, 4, 'X', 0);
+
+ clear_iovec_buffers(var_read_iovs, 4);
+
+ fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
+
+ io_uring_do_vec_io_op(&s, fd, IORING_OP_WRITEV, var_write_iovs, 4, 0,
+ expected_size, &sig);
+
+ SAFE_FSYNC(fd);
+
+ io_uring_do_vec_io_op(&s, fd, IORING_OP_READV, var_read_iovs, 4, 0,
+ expected_size, &sig);
+
+ verify_iovec_data(var_write_iovs, var_read_iovs, 4, "Varying size vector I/O with zero-length buffer");
+
+ SAFE_CLOSE(fd);
+}
+
+static void run(void)
+{
+ clear_iovec_buffers(read_iovs, NUM_VECS);
+
+ test_writev_readv();
+ test_partial_vectors();
+ test_varying_sizes();
+}
+
+static void setup(void)
+{
+ io_uring_setup_supported_by_kernel();
+ sigemptyset(&sig);
+ memset(&s, 0, sizeof(s));
+ io_uring_setup_queue(&s, QUEUE_DEPTH, 0);
+ init_iovec_buffers(write_iovs, NUM_VECS, 'A', 1);
+ clear_iovec_buffers(read_iovs, NUM_VECS);
+}
+
+static void cleanup(void)
+{
+ io_uring_cleanup_queue(&s, QUEUE_DEPTH);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_tmpdir = 1,
+ .bufs = (struct tst_buffers []) {
+ {&write_iovs, .iov_sizes = (int[]){VEC_SIZE, VEC_SIZE, VEC_SIZE, VEC_SIZE, -1}},
+ {&read_iovs, .iov_sizes = (int[]){VEC_SIZE, VEC_SIZE, VEC_SIZE, VEC_SIZE, -1}},
+ {&var_write_iovs, .iov_sizes = (int[]){VAR_BUF1_SIZE, 0, VAR_BUF2_SIZE, VAR_BUF3_SIZE, -1}},
+ {&var_read_iovs, .iov_sizes = (int[]){VAR_BUF1_SIZE, 0, VAR_BUF2_SIZE, VAR_BUF3_SIZE, -1}},
+ {}
+ },
+ .save_restore = (const struct tst_path_val[]) {
+ {"/proc/sys/kernel/io_uring_disabled", "0",
+ TST_SR_SKIP_MISSING | TST_SR_TCONF_RO},
+ {}
+ }
+};
--
2.39.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [LTP] [PATCH 2/2] io_uring: remove unused io_uring_init_buffer_pattern()
2026-04-16 12:16 [LTP] [PATCH v6 1/2] io_uring: Add test for READV and WRITEV operations Sachin Sant
@ 2026-04-16 12:16 ` Sachin Sant
2026-04-16 13:47 ` [LTP] io_uring: Add test for READV and WRITEV operations linuxtestproject.agent
2026-05-06 11:45 ` [LTP] [PATCH v6 1/2] " Andrea Cervesato via ltp
2 siblings, 0 replies; 6+ messages in thread
From: Sachin Sant @ 2026-04-16 12:16 UTC (permalink / raw)
To: ltp
The io_uring04 test merged the functionality of
io_uring_init_buffer_pattern() into the unified function
init_iovec_buffers(). Since io_uring_init_buffer_pattern()
was not used by any existing test, remove it.
Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
---
.../kernel/syscalls/io_uring/io_uring_common.h | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/testcases/kernel/syscalls/io_uring/io_uring_common.h b/testcases/kernel/syscalls/io_uring/io_uring_common.h
index aa31339fb..7816b55dc 100644
--- a/testcases/kernel/syscalls/io_uring/io_uring_common.h
+++ b/testcases/kernel/syscalls/io_uring/io_uring_common.h
@@ -230,19 +230,6 @@ static inline void io_uring_wait_cqe(struct io_uring_submit *s,
*cring->head = head + 1;
}
-/*
- * Initialize buffer with a repeating character pattern
- * Useful for creating test data with predictable patterns
- */
-static inline void io_uring_init_buffer_pattern(char *buf, size_t size,
- char pattern)
-{
- size_t i;
-
- for (i = 0; i < size; i++)
- buf[i] = pattern;
-}
-
/*
* Submit and wait for a non-vectored I/O operation
* Combines io_uring_submit_sqe() and io_uring_wait_cqe() with result reporting
--
2.39.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] io_uring: Add test for READV and WRITEV operations
2026-04-16 12:16 [LTP] [PATCH v6 1/2] io_uring: Add test for READV and WRITEV operations Sachin Sant
2026-04-16 12:16 ` [LTP] [PATCH 2/2] io_uring: remove unused io_uring_init_buffer_pattern() Sachin Sant
@ 2026-04-16 13:47 ` linuxtestproject.agent
2026-05-06 11:45 ` [LTP] [PATCH v6 1/2] " Andrea Cervesato via ltp
2 siblings, 0 replies; 6+ messages in thread
From: linuxtestproject.agent @ 2026-04-16 13:47 UTC (permalink / raw)
To: Sachin Sant; +Cc: ltp, LTP AI Reviewer
Hi Sachin,
On Thu, 16 Apr 2026 17:46:37 +0530, Sachin Sant wrote:
> io_uring: Add test for READV and WRITEV operations
Reviewed-by: LTP AI Reviewer <ltp-ai@noreply.github.com>
---
Note:
Our agent completed the review of the patch. The full review can be
found at: https://github.com/linux-test-project/ltp-agent/actions/runs/24513033939
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v6 1/2] io_uring: Add test for READV and WRITEV operations
2026-04-16 12:16 [LTP] [PATCH v6 1/2] io_uring: Add test for READV and WRITEV operations Sachin Sant
2026-04-16 12:16 ` [LTP] [PATCH 2/2] io_uring: remove unused io_uring_init_buffer_pattern() Sachin Sant
2026-04-16 13:47 ` [LTP] io_uring: Add test for READV and WRITEV operations linuxtestproject.agent
@ 2026-05-06 11:45 ` Andrea Cervesato via ltp
2026-05-06 12:11 ` Sachin Sant
2 siblings, 1 reply; 6+ messages in thread
From: Andrea Cervesato via ltp @ 2026-05-06 11:45 UTC (permalink / raw)
To: Sachin Sant; +Cc: ltp
Hi Sachin,
is it possible to separate the test into multiple ones?
Having multiple tests scenarios inside a single binary means
that (often) if one scenario fails, the others can't be tested.
In the kernel maintenance it's important to keep distinction
between tested features, so it's easier to debug a bug
in the system by cross-checking different scenarios.
We can have a helper header sharing the common operations and
to define multiple test files. It's a common pattern we use
in LTP.
Regards,
--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v6 1/2] io_uring: Add test for READV and WRITEV operations
2026-05-06 11:45 ` [LTP] [PATCH v6 1/2] " Andrea Cervesato via ltp
@ 2026-05-06 12:11 ` Sachin Sant
2026-05-06 12:27 ` Andrea Cervesato via ltp
0 siblings, 1 reply; 6+ messages in thread
From: Sachin Sant @ 2026-05-06 12:11 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
On 06/05/26 5:15 pm, Andrea Cervesato wrote:
> Hi Sachin,
>
> is it possible to separate the test into multiple ones?
Sure, can be done. Do you have any specific inputs on how to
split the test.
Split it into three tests, one for each of the following:
test_writev_readv();
test_partial_vectors();
test_varying_sizes();
> Having multiple tests scenarios inside a single binary means
> that (often) if one scenario fails, the others can't be tested.
Got it. Just curious, did you run into any test failure.
Thanks for the inputs.
--
Thanks
- Sachin
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v6 1/2] io_uring: Add test for READV and WRITEV operations
2026-05-06 12:11 ` Sachin Sant
@ 2026-05-06 12:27 ` Andrea Cervesato via ltp
0 siblings, 0 replies; 6+ messages in thread
From: Andrea Cervesato via ltp @ 2026-05-06 12:27 UTC (permalink / raw)
To: Sachin Sant; +Cc: ltp
> On 06/05/26 5:15 pm, Andrea Cervesato wrote:
> > Hi Sachin,
> >
> > is it possible to separate the test into multiple ones?
> Sure, can be done. Do you have any specific inputs on how to
> split the test.
>
> Split it into three tests, one for each of the following:
>
> test_writev_readv();
> test_partial_vectors();
> test_varying_sizes();
>
They can be split yes.
>
> > Having multiple tests scenarios inside a single binary means
> > that (often) if one scenario fails, the others can't be tested.
> Got it. Just curious, did you run into any test failure.
No, mine was a general rule just in case we face it.
Regards,
--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-05-06 12:27 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-16 12:16 [LTP] [PATCH v6 1/2] io_uring: Add test for READV and WRITEV operations Sachin Sant
2026-04-16 12:16 ` [LTP] [PATCH 2/2] io_uring: remove unused io_uring_init_buffer_pattern() Sachin Sant
2026-04-16 13:47 ` [LTP] io_uring: Add test for READV and WRITEV operations linuxtestproject.agent
2026-05-06 11:45 ` [LTP] [PATCH v6 1/2] " Andrea Cervesato via ltp
2026-05-06 12:11 ` Sachin Sant
2026-05-06 12:27 ` Andrea Cervesato via ltp
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox