Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/nop: add support for testing registered files and buffers

Useful for testing performance/efficiency impact of registered files
and buffers, vs (particularly) non-registered files.

Signed-off-by: Jens Axboe <axboe@kernel.dk>

+47 -5
+3
include/uapi/linux/io_uring.h
··· 416 416 * IORING_NOP_INJECT_RESULT Inject result from sqe->result 417 417 */ 418 418 #define IORING_NOP_INJECT_RESULT (1U << 0) 419 + #define IORING_NOP_FILE (1U << 1) 420 + #define IORING_NOP_FIXED_FILE (1U << 2) 421 + #define IORING_NOP_FIXED_BUFFER (1U << 3) 419 422 420 423 /* 421 424 * IO completion data structure (Completion Queue Entry)
+44 -5
io_uring/nop.c
··· 8 8 #include <uapi/linux/io_uring.h> 9 9 10 10 #include "io_uring.h" 11 + #include "rsrc.h" 11 12 #include "nop.h" 12 13 13 14 struct io_nop { 14 15 /* NOTE: kiocb has the file as the first member, so don't do it here */ 15 16 struct file *file; 16 17 int result; 18 + int fd; 19 + int buffer; 20 + unsigned int flags; 17 21 }; 22 + 23 + #define NOP_FLAGS (IORING_NOP_INJECT_RESULT | IORING_NOP_FIXED_FILE | \ 24 + IORING_NOP_FIXED_BUFFER | IORING_NOP_FILE) 18 25 19 26 int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 20 27 { 21 - unsigned int flags; 22 28 struct io_nop *nop = io_kiocb_to_cmd(req, struct io_nop); 23 29 24 - flags = READ_ONCE(sqe->nop_flags); 25 - if (flags & ~IORING_NOP_INJECT_RESULT) 30 + nop->flags = READ_ONCE(sqe->nop_flags); 31 + if (nop->flags & ~NOP_FLAGS) 26 32 return -EINVAL; 27 33 28 - if (flags & IORING_NOP_INJECT_RESULT) 34 + if (nop->flags & IORING_NOP_INJECT_RESULT) 29 35 nop->result = READ_ONCE(sqe->len); 30 36 else 31 37 nop->result = 0; 38 + if (nop->flags & IORING_NOP_FIXED_FILE) 39 + nop->fd = READ_ONCE(sqe->fd); 40 + if (nop->flags & IORING_NOP_FIXED_BUFFER) 41 + nop->buffer = READ_ONCE(sqe->buf_index); 32 42 return 0; 33 43 } 34 44 35 45 int io_nop(struct io_kiocb *req, unsigned int issue_flags) 36 46 { 37 47 struct io_nop *nop = io_kiocb_to_cmd(req, struct io_nop); 48 + int ret = nop->result; 38 49 39 - if (nop->result < 0) 50 + if (nop->flags & IORING_NOP_FILE) { 51 + if (nop->flags & IORING_NOP_FIXED_FILE) { 52 + req->file = io_file_get_fixed(req, nop->fd, issue_flags); 53 + req->flags |= REQ_F_FIXED_FILE; 54 + } else { 55 + req->file = io_file_get_normal(req, nop->fd); 56 + } 57 + if (!req->file) { 58 + ret = -EBADF; 59 + goto done; 60 + } 61 + } 62 + if (nop->flags & IORING_NOP_FIXED_BUFFER) { 63 + struct io_ring_ctx *ctx = req->ctx; 64 + struct io_mapped_ubuf *imu; 65 + int idx; 66 + 67 + ret = -EFAULT; 68 + io_ring_submit_lock(ctx, issue_flags); 69 + if (nop->buffer < ctx->nr_user_bufs) { 70 + idx = array_index_nospec(nop->buffer, ctx->nr_user_bufs); 71 + imu = READ_ONCE(ctx->user_bufs[idx]); 72 + io_req_set_rsrc_node(req, ctx); 73 + ret = 0; 74 + } 75 + io_ring_submit_unlock(ctx, issue_flags); 76 + } 77 + done: 78 + if (ret < 0) 40 79 req_set_fail(req); 41 80 io_req_set_res(req, nop->result, 0); 42 81 return IOU_OK;