The following changes since commit a191635ad42893a60d0a917b27e97e3fc73f7fee: engines/io_uring_cmd: do not send data buffer for write zeroes (2024-10-28 12:25:15 -0400) are available in the Git repository at: git://git.kernel.dk/fio.git master for you to fetch changes up to 6a193ce90a4d8958d5000809dd8e3286e8215d0f: t/io_uring: add symbolic defines for NOP flags (2024-11-04 10:27:06 -0700) ---------------------------------------------------------------- Jens Axboe (3): t/io_uring: register single buffer for whole IO region t/io_uring: enable registered file/buffer testing with NOP t/io_uring: add symbolic defines for NOP flags os/linux/io_uring.h | 5 +++++ t/io_uring.c | 58 +++++++++++++++++++++++++++++++++-------------------- 2 files changed, 41 insertions(+), 22 deletions(-) --- Diff of recent changes: diff --git a/os/linux/io_uring.h b/os/linux/io_uring.h index 1040f690..b3876381 100644 --- a/os/linux/io_uring.h +++ b/os/linux/io_uring.h @@ -245,6 +245,11 @@ enum { #define IORING_POLL_UPDATE_EVENTS (1U << 1) #define IORING_POLL_UPDATE_USER_DATA (1U << 2) +#define IORING_NOP_INJECT_RESULT (1U << 0) +#define IORING_NOP_FILE (1U << 1) +#define IORING_NOP_FIXED_FILE (1U << 2) +#define IORING_NOP_FIXED_BUFFER (1U << 3) + /* * IO completion data structure (Completion Queue Entry) */ diff --git a/t/io_uring.c b/t/io_uring.c index 0fa01837..dec9552b 100644 --- a/t/io_uring.c +++ b/t/io_uring.c @@ -137,6 +137,7 @@ static int buffered = 0; /* use buffered IO, not O_DIRECT */ static int sq_thread_poll = 0; /* use kernel submission/poller thread */ static int sq_thread_cpu = -1; /* pin above thread to this CPU */ static int do_nop = 0; /* no-op SQ ring commands */ +static int use_files = 1; static int nthreads = 1; static int stats = 0; /* generate IO stats */ static int aio = 0; /* use libaio */ @@ -398,20 +399,23 @@ static void add_stat(struct submitter *s, int clock_index, int nr) static int io_uring_register_buffers(struct submitter *s) { - if (do_nop) - return 0; + int ret; - return syscall(__NR_io_uring_register, s->ring_fd, - IORING_REGISTER_BUFFERS, s->iovecs, roundup_pow2(depth)); + /* + * All iovecs are filled in case of readv, but it's all contig + * from vec0. Just register a single buffer for all buffers. + */ + s->iovecs[0].iov_len = bs * roundup_pow2(depth); + ret = syscall(__NR_io_uring_register, s->ring_fd, + IORING_REGISTER_BUFFERS, s->iovecs, 1); + s->iovecs[0].iov_len = bs; + return ret; } static int io_uring_register_files(struct submitter *s) { int i; - if (do_nop) - return 0; - s->fds = calloc(s->nr_files, sizeof(__s32)); for (i = 0; i < s->nr_files; i++) { s->fds[i] = s->files[i].real_fd; @@ -539,13 +543,24 @@ static void init_io(struct submitter *s, unsigned index) struct io_uring_sqe *sqe = &s->sqes[index]; struct file *f; + f = get_next_file(s); + if (do_nop) { + sqe->rw_flags = IORING_NOP_FILE; + if (register_files) { + sqe->fd = f->fixed_fd; + sqe->rw_flags |= IORING_NOP_FIXED_FILE; + } else { + sqe->fd = f->real_fd; + } + if (fixedbufs) + sqe->rw_flags |= IORING_NOP_FIXED_BUFFER; + sqe->rw_flags |= IORING_NOP_INJECT_RESULT; + sqe->len = bs; sqe->opcode = IORING_OP_NOP; return; } - f = get_next_file(s); - if (register_files) { sqe->flags = IOSQE_FIXED_FILE; sqe->fd = f->fixed_fd; @@ -557,7 +572,7 @@ static void init_io(struct submitter *s, unsigned index) sqe->opcode = IORING_OP_READ_FIXED; sqe->addr = (unsigned long) s->iovecs[index].iov_base; sqe->len = bs; - sqe->buf_index = index; + sqe->buf_index = 0; } else if (!vectored) { sqe->opcode = IORING_OP_READ; sqe->addr = (unsigned long) s->iovecs[index].iov_base; @@ -710,7 +725,7 @@ static int reap_events_uring(struct submitter *s) if (head == tail) break; cqe = &ring->cqes[head & cq_ring_mask]; - if (!do_nop) { + if (use_files) { int fileno = cqe->user_data & 0xffffffff; f = &s->files[fileno]; @@ -1003,10 +1018,12 @@ static int submitter_init(struct submitter *s) { int i, nr_batch, err; static int init_printed; + void *mem, *ptr; char buf[80]; + s->tid = gettid(); - printf("submitter=%d, tid=%d, file=%s, nfiles=%d, node=%d\n", s->index, s->tid, - s->filename, s->nr_files, s->numa_node); + printf("submitter=%d, tid=%d, file=%s, nfiles=%d, node=%d\n", s->index, + s->tid, s->filename, s->nr_files, s->numa_node); set_affinity(s); @@ -1016,14 +1033,11 @@ static int submitter_init(struct submitter *s) for (i = 0; i < MAX_FDS; i++) s->files[i].fileno = i; - for (i = 0; i < roundup_pow2(depth); i++) { - void *buf; - - buf = allocate_mem(s, bs); - if (!buf) - return -1; - s->iovecs[i].iov_base = buf; + mem = allocate_mem(s, bs * roundup_pow2(depth)); + for (i = 0, ptr = mem; i < roundup_pow2(depth); i++) { + s->iovecs[i].iov_base = ptr; s->iovecs[i].iov_len = bs; + ptr += bs; } if (use_sync) { @@ -1683,7 +1697,7 @@ int main(int argc, char *argv[]) j = 0; i = optind; nfiles = argc - i; - if (!do_nop) { + if (use_files) { if (!nfiles) { printf("No files specified\n"); usage(argv[0], 1); @@ -1696,7 +1710,7 @@ int main(int argc, char *argv[]) threads_rem = nthreads - threads_per_f * nfiles; } } - while (!do_nop && i < argc) { + while (use_files && i < argc) { int k, limit; memset(&f, 0, sizeof(f));