io_uring/nop: add support for IORING_SETUP_CQE_MIXED
authorJens Axboe <axboe@kernel.dk>
Thu, 7 Aug 2025 20:22:16 +0000 (14:22 -0600)
committerJens Axboe <axboe@kernel.dk>
Sat, 9 Aug 2025 14:38:04 +0000 (08:38 -0600)
This adds support for setting IORING_NOP_CQE32 as a flag for a NOP
command, in which case a 32b CQE will be posted rather than a regular
one. This is the default if the ring has been setup with
IORING_SETUP_CQE32. If the ring has been setup with
IORING_SETUP_CQE_MIXED, then 16b CQEs will be posted without this flag
set, and 32b CQEs if this flag is set. For the latter case, sqe->off is
what will be posted as cqe->big_cqe[0] and sqe->addr is what will be
posted as cqe->big_cqe[1].

Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/uapi/linux/io_uring.h
io_uring/nop.c

index 9396afb01dc80fb1efd455a769e22bac274ec1cf..33b386f43d47cdd090efa19c36d88da7f719847e 100644 (file)
@@ -460,6 +460,7 @@ enum io_uring_msg_ring_flags {
 #define IORING_NOP_FIXED_FILE          (1U << 2)
 #define IORING_NOP_FIXED_BUFFER                (1U << 3)
 #define IORING_NOP_TW                  (1U << 4)
+#define IORING_NOP_CQE32               (1U << 5)
 
 /*
  * IO completion data structure (Completion Queue Entry)
index 20ed0f85b1c2b66130b27cfeeb6539e86accf284..3caf07878f8acaff85c0f6ecd75d1fbe648c453f 100644 (file)
@@ -17,11 +17,13 @@ struct io_nop {
        int             result;
        int             fd;
        unsigned int    flags;
+       __u64           extra1;
+       __u64           extra2;
 };
 
 #define NOP_FLAGS      (IORING_NOP_INJECT_RESULT | IORING_NOP_FIXED_FILE | \
                         IORING_NOP_FIXED_BUFFER | IORING_NOP_FILE | \
-                        IORING_NOP_TW)
+                        IORING_NOP_TW | IORING_NOP_CQE32)
 
 int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
@@ -41,6 +43,14 @@ int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
                nop->fd = -1;
        if (nop->flags & IORING_NOP_FIXED_BUFFER)
                req->buf_index = READ_ONCE(sqe->buf_index);
+       if (nop->flags & IORING_NOP_CQE32) {
+               struct io_ring_ctx *ctx = req->ctx;
+
+               if (!(ctx->flags & (IORING_SETUP_CQE32|IORING_SETUP_CQE_MIXED)))
+                       return -EINVAL;
+               nop->extra1 = READ_ONCE(sqe->off);
+               nop->extra2 = READ_ONCE(sqe->addr);
+       }
        return 0;
 }
 
@@ -68,7 +78,10 @@ int io_nop(struct io_kiocb *req, unsigned int issue_flags)
 done:
        if (ret < 0)
                req_set_fail(req);
-       io_req_set_res(req, nop->result, 0);
+       if (nop->flags & IORING_NOP_CQE32)
+               io_req_set_res32(req, nop->result, 0, nop->extra1, nop->extra2);
+       else
+               io_req_set_res(req, nop->result, 0);
        if (nop->flags & IORING_NOP_TW) {
                req->io_task_work.func = io_req_task_complete;
                io_req_task_work_add(req);