Linux Test Project
 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

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox