All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v2 1/4] io_uring: Redesign common helpers to follow liburing API conventions
@ 2026-06-14 17:47 Sebastian Chlad
  2026-06-14 17:47 ` [LTP] [PATCH v2 2/4] io_uring01: Update to use new io_uring_common.h helpers Sebastian Chlad
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Sebastian Chlad @ 2026-06-14 17:47 UTC (permalink / raw)
  To: ltp; +Cc: Sebastian Chlad

Replace coupled submit and wait helpers with a proper liburing-style API:
- io_uring_get_sqe(): get next SQE slot from the submission ring
- io_uring_prep_rw(): generic SQE fill for read/write operations
- io_uring_prep_read/write/readv/writev(): operation-specific prep helpers
- io_uring_sqe_set_data64(): set user_data explicitly on the SQE
- io_uring_submit(): submit all pending SQEs to the kernel
- io_uring_cqe_wait(): wait for next CQE, return pointer without consuming it
- io_uring_cqe_seen(): advance the CQ head to mark a CQE as consumed

With the new API, each test controls SQE preparation, user_data
assignment, submission, CQE validation and result reporting explicitly
in its own body, matching how real io_uring applications are written.

Signed-off-by: Sebastian Chlad <sebastian.chlad@suse.com>
---
Changes in v2:
- Keep deprecated helpers alongside new ones for bisectability
  (removal moved to patch 4/4)
- Since doing the above, the io_uring_wait_cqe() had to be renames so it
  is renamed to io_uring_cqe_wait() to avoid name conflict with the
  pre-existing io_uring_wait_cqe() helper
- Use __atomic_store/__atomic_load with __ATOMIC_RELEASE/__ATOMIC_ACQUIRE

 .../syscalls/io_uring/io_uring_common.h       | 126 +++++++++++++++++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/testcases/kernel/syscalls/io_uring/io_uring_common.h b/testcases/kernel/syscalls/io_uring/io_uring_common.h
index aa31339fb..8ff024e5f 100644
--- a/testcases/kernel/syscalls/io_uring/io_uring_common.h
+++ b/testcases/kernel/syscalls/io_uring/io_uring_common.h
@@ -3,6 +3,8 @@
  * Copyright (C) 2026 IBM
  * Author: Sachin Sant <sachinp@linux.ibm.com>
  *
+ * Copyright (C) 2026 Sebastian Chlad <sebastian.chlad@suse.com>
+ *
  * Common definitions and helper functions for io_uring tests
  */
 
@@ -16,7 +18,6 @@
 #include "tst_test.h"
 #include "lapi/io_uring.h"
 
-/* Common structures for io_uring ring management */
 struct io_sq_ring {
 	unsigned int *head;
 	unsigned int *tail;
@@ -43,6 +44,7 @@ struct io_uring_submit {
 	size_t sq_ptr_size;
 	void *cq_ptr;
 	size_t cq_ptr_size;
+	unsigned int sq_pending;
 };
 
 /*
@@ -275,4 +277,126 @@ static inline void io_uring_do_vec_io_op(struct io_uring_submit *s, int fd,
 		expected_size);
 }
 
+/*
+ * Get the next available SQE slot from the submission ring.
+ * The SQE is zeroed and tracked as pending until io_uring_submit() is called.
+ */
+static inline struct io_uring_sqe *io_uring_get_sqe(struct io_uring_submit *s)
+{
+	struct io_sq_ring *sring = &s->sq_ring;
+	unsigned int index = (*sring->tail + s->sq_pending) & *sring->ring_mask;
+	struct io_uring_sqe *sqe = &s->sqes[index];
+
+	memset(sqe, 0, sizeof(*sqe));
+	sring->array[index] = index;
+	s->sq_pending++;
+
+	return sqe;
+}
+
+/*
+ * Generic SQE fill for read/write family operations.
+ * Does not touch user_data - caller sets it via io_uring_sqe_set_data64().
+ */
+static inline void io_uring_prep_rw(struct io_uring_sqe *sqe, int opcode,
+				    int fd, const void *addr, unsigned int len,
+				    off_t offset)
+{
+	sqe->opcode = opcode;
+	sqe->fd = fd;
+	sqe->addr = (unsigned long)addr;
+	sqe->len = len;
+	sqe->off = offset;
+}
+
+static inline void io_uring_prep_read(struct io_uring_sqe *sqe, int fd,
+				      void *buf, size_t len, off_t offset)
+{
+	io_uring_prep_rw(sqe, IORING_OP_READ, fd, buf, len, offset);
+}
+
+static inline void io_uring_prep_write(struct io_uring_sqe *sqe, int fd,
+				       const void *buf, size_t len, off_t offset)
+{
+	io_uring_prep_rw(sqe, IORING_OP_WRITE, fd, buf, len, offset);
+}
+
+static inline void io_uring_prep_readv(struct io_uring_sqe *sqe, int fd,
+				       struct iovec *iovs, int nr_vecs,
+				       off_t offset)
+{
+	io_uring_prep_rw(sqe, IORING_OP_READV, fd, iovs, nr_vecs, offset);
+}
+
+static inline void io_uring_prep_writev(struct io_uring_sqe *sqe, int fd,
+					struct iovec *iovs, int nr_vecs,
+					off_t offset)
+{
+	io_uring_prep_rw(sqe, IORING_OP_WRITEV, fd, iovs, nr_vecs, offset);
+}
+
+/*
+ * Set the user_data field of an SQE. user_data is returned verbatim in the
+ * corresponding CQE and must be unique per in-flight request to allow correct
+ * correlation of completions.
+ */
+static inline void io_uring_sqe_set_data64(struct io_uring_sqe *sqe,
+					   uint64_t data)
+{
+	sqe->user_data = data;
+}
+
+/*
+ * Submit all pending SQEs to the kernel.
+ */
+static inline void io_uring_submit(struct io_uring_submit *s)
+{
+	unsigned int pending = s->sq_pending;
+
+	if (!pending)
+		return;
+
+	unsigned int tail = *s->sq_ring.tail + pending;
+
+	__atomic_store(s->sq_ring.tail, &tail, __ATOMIC_RELEASE);
+	s->sq_pending = 0;
+
+	if (io_uring_enter(s->ring_fd, pending, 0, 0, NULL) < 0)
+		tst_brk(TBROK | TERRNO, "io_uring_enter() failed");
+}
+
+/*
+ * Wait for the next CQE and return a pointer to it.
+ * Does not advance the CQ head - call io_uring_cqe_seen() when done.
+ */
+static inline struct io_uring_cqe *io_uring_cqe_wait(struct io_uring_submit *s,
+						      sigset_t *sig)
+{
+	struct io_cq_ring *cring = &s->cq_ring;
+	int ret;
+
+	ret = io_uring_enter(s->ring_fd, 0, 1, IORING_ENTER_GETEVENTS, sig);
+	if (ret < 0)
+		tst_brk(TBROK | TERRNO, "io_uring_enter() failed");
+
+	unsigned int cq_tail;
+
+	__atomic_load(cring->tail, &cq_tail, __ATOMIC_ACQUIRE);
+	if (*cring->head == cq_tail)
+		tst_brk(TBROK, "No completion event received");
+
+	return &cring->cqes[*cring->head & *cring->ring_mask];
+}
+
+/*
+ * Mark the current CQE as consumed, advancing the CQ head.
+ */
+static inline void io_uring_cqe_seen(struct io_uring_submit *s)
+{
+	unsigned int head = *s->cq_ring.head + 1;
+
+	__atomic_store(s->cq_ring.head, &head, __ATOMIC_RELEASE);
+}
+
+
 #endif /* IO_URING_COMMON_H */
-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [LTP] [PATCH v2 2/4] io_uring01: Update to use new io_uring_common.h helpers
  2026-06-14 17:47 [LTP] [PATCH v2 1/4] io_uring: Redesign common helpers to follow liburing API conventions Sebastian Chlad
@ 2026-06-14 17:47 ` Sebastian Chlad
  2026-06-14 17:47 ` [LTP] [PATCH v2 3/4] io_uring03: " Sebastian Chlad
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sebastian Chlad @ 2026-06-14 17:47 UTC (permalink / raw)
  To: ltp; +Cc: Sebastian Chlad

Signed-off-by: Sebastian Chlad <sebastian.chlad@suse.com>
---
 .../kernel/syscalls/io_uring/io_uring01.c     | 64 ++++++++-----------
 1 file changed, 26 insertions(+), 38 deletions(-)

diff --git a/testcases/kernel/syscalls/io_uring/io_uring01.c b/testcases/kernel/syscalls/io_uring/io_uring01.c
index 1d2029fdf..d9dac8c10 100644
--- a/testcases/kernel/syscalls/io_uring/io_uring01.c
+++ b/testcases/kernel/syscalls/io_uring/io_uring01.c
@@ -5,11 +5,14 @@
  *
  * Copyright (C) 2020 Cyril Hrubis <chrubis@suse.cz>
  *
+ * Copyright (C) 2026 Sebastian Chlad <sebastian.chlad@suse.com>
+ *
  * Tests for asynchronous I/O raw API i.e io_uring_setup(), io_uring_register()
- * and io_uring_enter(). This tests validate basic API operation by creating a
+ * and io_uring_enter(). This test validates basic API operation by creating a
  * submission queue and a completion queue using io_uring_setup(). User buffer
  * registered in the kernel for long term operation using io_uring_register().
- * This tests initiates I/O operations with the help of io_uring_enter().
+ * This test initiates I/O operations using io_uring_submit() and
+ * io_uring_cqe_wait() helpers built on top of io_uring_enter().
  */
 #include "io_uring_common.h"
 
@@ -27,7 +30,6 @@ static struct tcase {
 };
 
 static struct io_uring_submit s;
-static sigset_t sig;
 static struct iovec *iov;
 
 static int setup_io_uring_test(struct io_uring_submit *s, struct tcase *tc)
@@ -58,72 +60,58 @@ static void check_buffer(char *buffer, size_t len)
 
 static void drain_uring_cq(struct io_uring_submit *s, unsigned int exp_events)
 {
-	struct io_cq_ring *cring = &s->cq_ring;
-	unsigned int head = *cring->head;
 	unsigned int events = 0;
+	struct io_uring_cqe *cqe;
+	struct iovec *iovecs;
 
-	for (head = *cring->head; head != *cring->tail; head++) {
-		struct io_uring_cqe *cqe = &cring->cqes[head & *s->cq_ring.ring_mask];
-
+	while (events < exp_events) {
+		cqe = io_uring_cqe_wait(s, NULL);
 		events++;
 
 		if (cqe->res < 0) {
 			tst_res(TFAIL, "CQE result %s", tst_strerrno(-cqe->res));
 		} else {
-			struct iovec *iovecs = (void*)cqe->user_data;
+			iovecs = (void *)cqe->user_data;
 
 			if (cqe->res == BLOCK_SZ)
 				tst_res(TPASS, "CQE result %i", cqe->res);
 			else
-				tst_res(TFAIL, "CQE result %i expected %i", cqe->res, BLOCK_SZ);
+				tst_res(TFAIL, "CQE result %i expected %i",
+					cqe->res, BLOCK_SZ);
 
 			check_buffer(iovecs[0].iov_base, cqe->res);
 		}
-	}
 
-	*cring->head = head;
-
-	if (exp_events == events) {
-		tst_res(TPASS, "Got %u completion events", events);
-		return;
+		io_uring_cqe_seen(s);
 	}
 
-	tst_res(TFAIL, "Got %u completion events expected %u",
-	        events, exp_events);
+	if (exp_events == events)
+		tst_res(TPASS, "Got %u completion events", events);
+	else
+		tst_res(TFAIL, "Got %u completion events expected %u",
+			events, exp_events);
 }
 
 static int submit_to_uring_sq(struct io_uring_submit *s, struct tcase *tc)
 {
-	int ret;
+	struct io_uring_sqe *sqe;
 	int fd;
 
 	memset(iov->iov_base, 0, iov->iov_len);
 
-	ret = io_uring_register(s->ring_fd, tc->register_opcode,
-				iov, QUEUE_DEPTH);
-	if (ret == 0) {
-		tst_res(TPASS, "io_uring_register() passed");
-	} else {
+	if (io_uring_register(s->ring_fd, tc->register_opcode,
+			      iov, QUEUE_DEPTH)) {
 		tst_res(TFAIL | TERRNO, "io_uring_register() failed");
 		return 1;
 	}
+	tst_res(TPASS, "io_uring_register() passed");
 
 	fd = SAFE_OPEN(TEST_FILE, O_RDONLY);
 
-	/* Submit SQE using common helper */
-	io_uring_submit_sqe_internal(s, fd, tc->enter_flags,
-				     (unsigned long)iov->iov_base,
-				     BLOCK_SZ, 0,
-				     (unsigned long long)iov);
-
-	ret = io_uring_enter(s->ring_fd, 1, 1, IORING_ENTER_GETEVENTS, &sig);
-	if (ret == 1) {
-		tst_res(TPASS, "io_uring_enter() waited for 1 event");
-	} else {
-		tst_res(TFAIL | TERRNO, "io_uring_enter() returned %i", ret);
-		SAFE_CLOSE(fd);
-		return 1;
-	}
+	sqe = io_uring_get_sqe(s);
+	io_uring_prep_rw(sqe, tc->enter_flags, fd, iov->iov_base, BLOCK_SZ, 0);
+	io_uring_sqe_set_data64(sqe, (uint64_t)iov);
+	io_uring_submit(s);
 
 	SAFE_CLOSE(fd);
 	return 0;
-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [LTP] [PATCH v2 3/4] io_uring03: Update to use new io_uring_common.h helpers
  2026-06-14 17:47 [LTP] [PATCH v2 1/4] io_uring: Redesign common helpers to follow liburing API conventions Sebastian Chlad
  2026-06-14 17:47 ` [LTP] [PATCH v2 2/4] io_uring01: Update to use new io_uring_common.h helpers Sebastian Chlad
@ 2026-06-14 17:47 ` Sebastian Chlad
  2026-06-14 17:47 ` [LTP] [PATCH v2 4/4] io_uring: Remove deprecated helpers Sebastian Chlad
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sebastian Chlad @ 2026-06-14 17:47 UTC (permalink / raw)
  To: ltp; +Cc: Sebastian Chlad

Signed-off-by: Sebastian Chlad <sebastian.chlad@suse.com>
---
 .../kernel/syscalls/io_uring/io_uring03.c     | 77 +++++++++++++++----
 1 file changed, 60 insertions(+), 17 deletions(-)

diff --git a/testcases/kernel/syscalls/io_uring/io_uring03.c b/testcases/kernel/syscalls/io_uring/io_uring03.c
index d3b9cff82..521ec0942 100644
--- a/testcases/kernel/syscalls/io_uring/io_uring03.c
+++ b/testcases/kernel/syscalls/io_uring/io_uring03.c
@@ -2,6 +2,9 @@
 /*
  * Copyright (C) 2026 IBM
  * Author: Sachin Sant <sachinp@linux.ibm.com>
+ *
+ * Copyright (C) 2026 Sebastian Chlad <sebastian.chlad@suse.com>
+ *
  */
 /*
  * Test IORING_OP_READ and IORING_OP_WRITE operations.
@@ -53,53 +56,93 @@ static void verify_data_integrity(const char *test_name)
 
 static void test_write_read(void)
 {
+	struct io_uring_sqe *sqe;
+	struct io_uring_cqe *cqe;
 	int fd;
 
 	init_buffer('A');
-
 	fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
 
 	tst_res(TINFO, "Testing IORING_OP_WRITE");
-	io_uring_do_io_op(&s, fd, IORING_OP_WRITE, write_buf, BLOCK_SZ, 0,
-			  &sig);
+	sqe = io_uring_get_sqe(&s);
+	io_uring_prep_write(sqe, fd, write_buf, BLOCK_SZ, 0);
+	io_uring_sqe_set_data64(sqe, 1);
+	io_uring_submit(&s);
+
+	cqe = io_uring_cqe_wait(&s, &sig);
+	if (cqe->res != BLOCK_SZ)
+		tst_brk(TBROK, "IORING_OP_WRITE failed: res=%d", cqe->res);
+	tst_res(TPASS, "IORING_OP_WRITE: %d bytes written", cqe->res);
+	io_uring_cqe_seen(&s);
 
 	SAFE_FSYNC(fd);
 
 	tst_res(TINFO, "Testing IORING_OP_READ");
 	memset(read_buf, 0, BLOCK_SZ);
-	io_uring_do_io_op(&s, fd, IORING_OP_READ, read_buf, BLOCK_SZ, 0,
-			  &sig);
+	sqe = io_uring_get_sqe(&s);
+	io_uring_prep_read(sqe, fd, read_buf, BLOCK_SZ, 0);
+	io_uring_sqe_set_data64(sqe, 2);
+	io_uring_submit(&s);
 
-	verify_data_integrity("Basic I/O");
+	cqe = io_uring_cqe_wait(&s, &sig);
+	if (cqe->res != BLOCK_SZ)
+		tst_brk(TBROK, "IORING_OP_READ failed: res=%d", cqe->res);
+	tst_res(TPASS, "IORING_OP_READ: %d bytes read", cqe->res);
+	io_uring_cqe_seen(&s);
 
+	verify_data_integrity("Basic I/O");
 	SAFE_CLOSE(fd);
 }
 
 static void test_partial_io(void)
 {
-	int fd;
+	struct io_uring_sqe *sqe;
+	struct io_uring_cqe *cqe;
 	size_t half = BLOCK_SZ / 2;
+	int fd;
 
 	tst_res(TINFO, "Testing partial I/O operations");
-
 	init_buffer('a');
-
 	fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
 
-	io_uring_do_io_op(&s, fd, IORING_OP_WRITE, write_buf, half, 0,
-			  &sig);
-
-	io_uring_do_io_op(&s, fd, IORING_OP_WRITE, write_buf + half, half,
-			  half, &sig);
+	sqe = io_uring_get_sqe(&s);
+	io_uring_prep_write(sqe, fd, write_buf, half, 0);
+	io_uring_sqe_set_data64(sqe, 1);
+	io_uring_submit(&s);
+
+	cqe = io_uring_cqe_wait(&s, &sig);
+	if (cqe->res != (int)half)
+		tst_brk(TBROK, "IORING_OP_WRITE failed: res=%d", cqe->res);
+	tst_res(TPASS, "IORING_OP_WRITE: %d bytes written at offset 0", cqe->res);
+	io_uring_cqe_seen(&s);
+
+	sqe = io_uring_get_sqe(&s);
+	io_uring_prep_write(sqe, fd, write_buf + half, half, half);
+	io_uring_sqe_set_data64(sqe, 2);
+	io_uring_submit(&s);
+
+	cqe = io_uring_cqe_wait(&s, &sig);
+	if (cqe->res != (int)half)
+		tst_brk(TBROK, "IORING_OP_WRITE failed: res=%d", cqe->res);
+	tst_res(TPASS, "IORING_OP_WRITE: %d bytes written at offset %zu",
+		cqe->res, half);
+	io_uring_cqe_seen(&s);
 
 	SAFE_FSYNC(fd);
 
 	memset(read_buf, 0, BLOCK_SZ);
-	io_uring_do_io_op(&s, fd, IORING_OP_READ, read_buf, BLOCK_SZ, 0,
-			  &sig);
+	sqe = io_uring_get_sqe(&s);
+	io_uring_prep_read(sqe, fd, read_buf, BLOCK_SZ, 0);
+	io_uring_sqe_set_data64(sqe, 3);
+	io_uring_submit(&s);
 
-	verify_data_integrity("Partial I/O");
+	cqe = io_uring_cqe_wait(&s, &sig);
+	if (cqe->res != BLOCK_SZ)
+		tst_brk(TBROK, "IORING_OP_READ failed: res=%d", cqe->res);
+	tst_res(TPASS, "IORING_OP_READ: %d bytes read", cqe->res);
+	io_uring_cqe_seen(&s);
 
+	verify_data_integrity("Partial I/O");
 	SAFE_CLOSE(fd);
 }
 
-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [LTP] [PATCH v2 4/4] io_uring: Remove deprecated helpers
  2026-06-14 17:47 [LTP] [PATCH v2 1/4] io_uring: Redesign common helpers to follow liburing API conventions Sebastian Chlad
  2026-06-14 17:47 ` [LTP] [PATCH v2 2/4] io_uring01: Update to use new io_uring_common.h helpers Sebastian Chlad
  2026-06-14 17:47 ` [LTP] [PATCH v2 3/4] io_uring03: " Sebastian Chlad
@ 2026-06-14 17:47 ` Sebastian Chlad
  2026-06-14 18:19 ` [LTP] io_uring: Redesign common helpers to follow liburing API conventions linuxtestproject.agent
  2026-06-15 12:58 ` [LTP] [PATCH v2 1/4] " Andrea Cervesato via ltp
  4 siblings, 0 replies; 6+ messages in thread
From: Sebastian Chlad @ 2026-06-14 17:47 UTC (permalink / raw)
  To: ltp; +Cc: Sebastian Chlad

The old io_uring_do_io_op() and io_uring_do_vec_io_op() helpers are
removed. They coupled SQE submission with an immediate CQE wait, making
tests effectively synchronous, and emitted tst_res(TPASS) from inside
the helper, hiding where test results came from. They also set user_data
to the opcode value, which is meaningless as a per-request tag and would
cause spurious passes in any test with multiple in-flight SQEs of the
same opcode.

Signed-off-by: Sebastian Chlad <sebastian.chlad@suse.com>
---
 .../syscalls/io_uring/io_uring_common.h       | 168 +-----------------
 1 file changed, 4 insertions(+), 164 deletions(-)

diff --git a/testcases/kernel/syscalls/io_uring/io_uring_common.h b/testcases/kernel/syscalls/io_uring/io_uring_common.h
index 8ff024e5f..ae0fff432 100644
--- a/testcases/kernel/syscalls/io_uring/io_uring_common.h
+++ b/testcases/kernel/syscalls/io_uring/io_uring_common.h
@@ -18,6 +18,7 @@
 #include "tst_test.h"
 #include "lapi/io_uring.h"
 
+/* Common structures for io_uring ring management */
 struct io_sq_ring {
 	unsigned int *head;
 	unsigned int *tail;
@@ -118,165 +119,6 @@ static inline void io_uring_cleanup_queue(struct io_uring_submit *s,
 		SAFE_CLOSE(s->ring_fd);
 }
 
-/*
- * Internal helper to submit a single SQE to the submission queue
- * Used by both vectored and non-vectored I/O operations
- */
-static inline void io_uring_submit_sqe_internal(struct io_uring_submit *s,
-						int fd, int opcode,
-						unsigned long addr,
-						unsigned int len,
-						off_t offset,
-						unsigned long long user_data)
-{
-	struct io_sq_ring *sring = &s->sq_ring;
-	unsigned int tail, index;
-	struct io_uring_sqe *sqe;
-
-	tail = *sring->tail;
-	index = tail & *sring->ring_mask;
-	sqe = &s->sqes[index];
-
-	memset(sqe, 0, sizeof(*sqe));
-	sqe->opcode = opcode;
-	sqe->fd = fd;
-	sqe->addr = addr;
-	sqe->len = len;
-	sqe->off = offset;
-	sqe->user_data = user_data;
-
-	sring->array[index] = index;
-	tail++;
-
-	*sring->tail = tail;
-}
-
-/*
- * Submit a single SQE to the submission queue
- * For basic read/write operations (non-vectored)
- */
-static inline void io_uring_submit_sqe(struct io_uring_submit *s, int fd,
-				       int opcode, void *buf, size_t len,
-				       off_t offset)
-{
-	io_uring_submit_sqe_internal(s, fd, opcode, (unsigned long)buf,
-				     len, offset, opcode);
-}
-
-/*
- * Submit a vectored SQE to the submission queue
- * For readv/writev operations
- */
-static inline void io_uring_submit_sqe_vec(struct io_uring_submit *s, int fd,
-					   int opcode, struct iovec *iovs,
-					   int nr_vecs, off_t offset)
-{
-	io_uring_submit_sqe_internal(s, fd, opcode, (unsigned long)iovs,
-				     nr_vecs, offset, opcode);
-}
-
-/*
- * Map io_uring operation code to human-readable name
- */
-static inline const char *ioring_op_name(int op)
-{
-	switch (op) {
-	case IORING_OP_READV:
-		return "IORING_OP_READV";
-	case IORING_OP_WRITEV:
-		return "IORING_OP_WRITEV";
-	case IORING_OP_READ:
-		return "IORING_OP_READ";
-	case IORING_OP_WRITE:
-		return "IORING_OP_WRITE";
-	default:
-		return "UNKNOWN";
-	}
-}
-
-/*
- * Wait for and validate a completion queue entry
- * Aborts test on failure using tst_brk()
- */
-static inline void io_uring_wait_cqe(struct io_uring_submit *s,
-				     int expected_res, int expected_opcode,
-				     sigset_t *sig)
-{
-	struct io_cq_ring *cring = &s->cq_ring;
-	struct io_uring_cqe *cqe;
-	unsigned int head;
-	int ret;
-
-	ret = io_uring_enter(s->ring_fd, 1, 1, IORING_ENTER_GETEVENTS, sig);
-	if (ret < 0)
-		tst_brk(TBROK | TERRNO, "io_uring_enter() failed");
-
-	head = *cring->head;
-	if (head == *cring->tail)
-		tst_brk(TBROK, "No completion event received");
-
-	cqe = &cring->cqes[head & *cring->ring_mask];
-
-	if (cqe->user_data != (uint64_t)expected_opcode) {
-		*cring->head = head + 1;
-		tst_brk(TBROK, "Unexpected user_data: got %llu, expected %d",
-			(unsigned long long)cqe->user_data, expected_opcode);
-	}
-
-	if (cqe->res != expected_res) {
-		*cring->head = head + 1;
-		tst_brk(TBROK, "Operation failed: res=%d, expected=%d",
-			cqe->res, expected_res);
-	}
-
-	*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
- */
-static inline void io_uring_do_io_op(struct io_uring_submit *s, int fd,
-				     int op, void *buf, size_t len,
-				     off_t offset, sigset_t *sig)
-{
-	io_uring_submit_sqe(s, fd, op, buf, len, offset);
-	io_uring_wait_cqe(s, len, op, sig);
-	tst_res(TPASS, "OP=%s (%02x) fd=%i buf=%p len=%zu offset=%jd",
-		ioring_op_name(op), op, fd, buf, len, (intmax_t)offset);
-}
-
-/*
- * Submit and wait for a vectored I/O operation
- * Combines io_uring_submit_sqe_vec() and io_uring_wait_cqe() with
- * result reporting
- */
-static inline void io_uring_do_vec_io_op(struct io_uring_submit *s, int fd,
-					 int op, struct iovec *iovs,
-					 int nvecs, off_t offset,
-					 int expected_size, sigset_t *sig)
-{
-	io_uring_submit_sqe_vec(s, fd, op, iovs, nvecs, offset);
-	io_uring_wait_cqe(s, expected_size, op, sig);
-	tst_res(TPASS, "OP=%s (%02x) fd=%i iovs=%p nvecs=%i offset=%jd "
-		"expected_size=%i",
-		ioring_op_name(op), op, fd, iovs, nvecs, (intmax_t)offset,
-		expected_size);
-}
-
 /*
  * Get the next available SQE slot from the submission ring.
  * The SQE is zeroed and tracked as pending until io_uring_submit() is called.
@@ -352,12 +194,12 @@ static inline void io_uring_sqe_set_data64(struct io_uring_sqe *sqe,
 static inline void io_uring_submit(struct io_uring_submit *s)
 {
 	unsigned int pending = s->sq_pending;
+	unsigned int tail;
 
 	if (!pending)
 		return;
 
-	unsigned int tail = *s->sq_ring.tail + pending;
-
+	tail = *s->sq_ring.tail + pending;
 	__atomic_store(s->sq_ring.tail, &tail, __ATOMIC_RELEASE);
 	s->sq_pending = 0;
 
@@ -373,14 +215,13 @@ static inline struct io_uring_cqe *io_uring_cqe_wait(struct io_uring_submit *s,
 						      sigset_t *sig)
 {
 	struct io_cq_ring *cring = &s->cq_ring;
+	unsigned int cq_tail;
 	int ret;
 
 	ret = io_uring_enter(s->ring_fd, 0, 1, IORING_ENTER_GETEVENTS, sig);
 	if (ret < 0)
 		tst_brk(TBROK | TERRNO, "io_uring_enter() failed");
 
-	unsigned int cq_tail;
-
 	__atomic_load(cring->tail, &cq_tail, __ATOMIC_ACQUIRE);
 	if (*cring->head == cq_tail)
 		tst_brk(TBROK, "No completion event received");
@@ -398,5 +239,4 @@ static inline void io_uring_cqe_seen(struct io_uring_submit *s)
 	__atomic_store(s->cq_ring.head, &head, __ATOMIC_RELEASE);
 }
 
-
 #endif /* IO_URING_COMMON_H */
-- 
2.51.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [LTP] io_uring: Redesign common helpers to follow liburing API conventions
  2026-06-14 17:47 [LTP] [PATCH v2 1/4] io_uring: Redesign common helpers to follow liburing API conventions Sebastian Chlad
                   ` (2 preceding siblings ...)
  2026-06-14 17:47 ` [LTP] [PATCH v2 4/4] io_uring: Remove deprecated helpers Sebastian Chlad
@ 2026-06-14 18:19 ` linuxtestproject.agent
  2026-06-15 12:58 ` [LTP] [PATCH v2 1/4] " Andrea Cervesato via ltp
  4 siblings, 0 replies; 6+ messages in thread
From: linuxtestproject.agent @ 2026-06-14 18:19 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: ltp

Hi Sebastian,

On Sun, 14 Jun 2026 19:47:56 +0200, Sebastian Chlad wrote:
> io_uring: Redesign common helpers to follow liburing API conventions

--- [PATCH 2/4] ---

> io_uring01: Update to use new io_uring_common.h helpers
>
> Signed-off-by: Sebastian Chlad <sebastian.chlad@suse.com>

The commit body is empty. The diff is non-trivial (restructured CQE
consumption, separated submit from wait, dropped explicit
io_uring_enter return-value checking), so the motivation should be
stated in at least one sentence, e.g. why the switch to the new
helpers is needed.

--- [PATCH 3/4] ---

> io_uring03: Update to use new io_uring_common.h helpers
>
> Signed-off-by: Sebastian Chlad <sebastian.chlad@suse.com>

Same as patch 2 -- the body should explain why the change is made.

Verdict - Needs revision

---
Note:

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.

Regards,
LTP AI Reviewer

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [LTP] [PATCH v2 1/4] io_uring: Redesign common helpers to follow liburing API conventions
  2026-06-14 17:47 [LTP] [PATCH v2 1/4] io_uring: Redesign common helpers to follow liburing API conventions Sebastian Chlad
                   ` (3 preceding siblings ...)
  2026-06-14 18:19 ` [LTP] io_uring: Redesign common helpers to follow liburing API conventions linuxtestproject.agent
@ 2026-06-15 12:58 ` Andrea Cervesato via ltp
  4 siblings, 0 replies; 6+ messages in thread
From: Andrea Cervesato via ltp @ 2026-06-15 12:58 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: Sebastian Chlad, ltp

Hi Sebastian,

> +/*
> + * Generic SQE fill for read/write family operations.
> + * Does not touch user_data - caller sets it via io_uring_sqe_set_data64().
> + */
> +static inline void io_uring_prep_rw(struct io_uring_sqe *sqe, int opcode,
> +				    int fd, const void *addr, unsigned int len,
> +				    off_t offset)
> +{
> +	sqe->opcode = opcode;
> +	sqe->fd = fd;
> +	sqe->addr = (unsigned long)addr;
> +	sqe->len = len;
> +	sqe->off = offset;
> +}
> +
> +static inline void io_uring_prep_read(struct io_uring_sqe *sqe, int fd,
> +				      void *buf, size_t len, off_t offset)
> +{
> +	io_uring_prep_rw(sqe, IORING_OP_READ, fd, buf, len, offset);
> +}
> +
> +static inline void io_uring_prep_write(struct io_uring_sqe *sqe, int fd,
> +				       const void *buf, size_t len, off_t offset)
> +{
> +	io_uring_prep_rw(sqe, IORING_OP_WRITE, fd, buf, len, offset);
> +}
> +
> +static inline void io_uring_prep_readv(struct io_uring_sqe *sqe, int fd,
> +				       struct iovec *iovs, int nr_vecs,
> +				       off_t offset)
> +{
> +	io_uring_prep_rw(sqe, IORING_OP_READV, fd, iovs, nr_vecs, offset);
> +}
> +
> +static inline void io_uring_prep_writev(struct io_uring_sqe *sqe, int fd,
> +					struct iovec *iovs, int nr_vecs,
> +					off_t offset)
> +{
> +	io_uring_prep_rw(sqe, IORING_OP_WRITEV, fd, iovs, nr_vecs, offset);
> +}

I'm not an expert of liburing or io_uring in general, but aren't all
these functions quite redundant? They mostly do what we could simply
do inside test with 1 call and 1 argument difference.

> +
> +/*
> + * Set the user_data field of an SQE. user_data is returned verbatim in the
> + * corresponding CQE and must be unique per in-flight request to allow correct
> + * correlation of completions.
> + */
> +static inline void io_uring_sqe_set_data64(struct io_uring_sqe *sqe,
> +					   uint64_t data)
> +{
> +	sqe->user_data = data;
> +}

Uh? :-) same comment.

As I said, I'm not an expert on this technology, but I see that we are
overengineering something that is so simple as a 1-argument-difference
or 1 pointer assignment.

--
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-06-15 12:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-14 17:47 [LTP] [PATCH v2 1/4] io_uring: Redesign common helpers to follow liburing API conventions Sebastian Chlad
2026-06-14 17:47 ` [LTP] [PATCH v2 2/4] io_uring01: Update to use new io_uring_common.h helpers Sebastian Chlad
2026-06-14 17:47 ` [LTP] [PATCH v2 3/4] io_uring03: " Sebastian Chlad
2026-06-14 17:47 ` [LTP] [PATCH v2 4/4] io_uring: Remove deprecated helpers Sebastian Chlad
2026-06-14 18:19 ` [LTP] io_uring: Redesign common helpers to follow liburing API conventions linuxtestproject.agent
2026-06-15 12:58 ` [LTP] [PATCH v2 1/4] " Andrea Cervesato via ltp

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.