From a71ad043a3f4ad405911841e1fe5bb09823e3be2 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 12 Oct 2021 14:25:23 -0600 Subject: [PATCH] t/io_uring: add test support for pre mapping DMA buffers This is in no shape or form the final evolution or API of this, but easier to stuff it in here for testing. Signed-off-by: Jens Axboe --- t/io_uring.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/t/io_uring.c b/t/io_uring.c index 6af3b4d3..3edb3c34 100644 --- a/t/io_uring.c +++ b/t/io_uring.c @@ -110,6 +110,7 @@ static int batch_complete = BATCH_COMPLETE; static int bs = BS; static int polled = 1; /* use IO polling */ static int fixedbufs = 1; /* use fixed user buffers */ +static int dma_map; /* pre-map DMA buffers */ static int register_files = 1; /* use fixed files */ static int buffered = 0; /* use buffered IO, not O_DIRECT */ static int sq_thread_poll = 0; /* use kernel submission/poller thread */ @@ -130,6 +131,16 @@ static float plist[] = { 1.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 95.0, 99.0, 99.5, 99.9, 99.95, 99.99 }; static int plist_len = 17; +#ifndef IORING_REGISTER_MAP_BUFFERS +#define IORING_REGISTER_MAP_BUFFERS 20 +struct io_uring_map_buffers { + __s32 fd; + __u32 buf_start; + __u32 buf_end; + __u32 dir; +}; +#endif + static unsigned long cycles_to_nsec(unsigned long cycles) { uint64_t val; @@ -319,6 +330,26 @@ static void add_stat(struct submitter *s, int clock_index, int nr) #endif } +static int io_uring_map_buffers(struct submitter *s) +{ + struct io_uring_map_buffers map = { + .fd = s->files[0].real_fd, + .buf_start = 0, + .buf_end = depth, + .dir = 0, + }; + + if (do_nop) + return 0; + if (s->nr_files > 1) { + fprintf(stderr, "Can't map buffers with multiple files\n"); + return -1; + } + + return syscall(__NR_io_uring_register, s->ring_fd, + IORING_REGISTER_MAP_BUFFERS, &map, 1); +} + static int io_uring_register_buffers(struct submitter *s) { if (do_nop) @@ -945,6 +976,14 @@ static int setup_ring(struct submitter *s) perror("io_uring_register_buffers"); return 1; } + + if (dma_map) { + ret = io_uring_map_buffers(s); + if (ret < 0) { + perror("io_uring_map_buffers"); + return 1; + } + } } if (register_files) { @@ -1016,6 +1055,7 @@ static void usage(char *argv, int status) " -b : Block size, default %d\n" " -p : Polled IO, default %d\n" " -B : Fixed buffers, default %d\n" + " -R : DMA map fixed buffers, default %d\n" " -F : Register files, default %d\n" " -n : Number of threads, default %d\n" " -O : Use O_DIRECT, default %d\n" @@ -1025,8 +1065,8 @@ static void usage(char *argv, int status) " -a : Use legacy aio, default %d\n" " -r : Runtime in seconds, default %s\n", argv, DEPTH, BATCH_SUBMIT, BATCH_COMPLETE, BS, polled, - fixedbufs, register_files, nthreads, !buffered, do_nop, stats, aio, - runtime == 0 ? "unlimited" : runtime_str); + fixedbufs, dma_map, register_files, nthreads, !buffered, do_nop, + stats, aio, runtime == 0 ? "unlimited" : runtime_str); exit(status); } @@ -1086,7 +1126,7 @@ int main(int argc, char *argv[]) if (!do_nop && argc < 2) usage(argv[0], 1); - while ((opt = getopt(argc, argv, "d:s:c:b:p:B:F:n:N:O:t:T:a:r:h?")) != -1) { + while ((opt = getopt(argc, argv, "d:s:c:b:p:B:F:n:N:O:t:T:a:r:D:h?")) != -1) { switch (opt) { case 'a': aio = !!atoi(optarg); @@ -1147,6 +1187,9 @@ int main(int argc, char *argv[]) case 'r': runtime = atoi(optarg); break; + case 'D': + dma_map = !!atoi(optarg); + break; case 'h': case '?': default: @@ -1162,6 +1205,8 @@ int main(int argc, char *argv[]) batch_complete = depth; if (batch_submit > depth) batch_submit = depth; + if (!fixedbufs && dma_map) + dma_map = 0; submitter = calloc(nthreads, sizeof(*submitter) + depth * sizeof(struct iovec)); @@ -1261,7 +1306,7 @@ int main(int argc, char *argv[]) } } s = get_submitter(0); - printf("polled=%d, fixedbufs=%d, register_files=%d, buffered=%d, QD=%d\n", polled, fixedbufs, register_files, buffered, depth); + printf("polled=%d, fixedbufs=%d/%d, register_files=%d, buffered=%d, QD=%d\n", polled, fixedbufs, dma_map, register_files, buffered, depth); if (!aio) printf("Engine=io_uring, sq_ring=%d, cq_ring=%d\n", *s->sq_ring.ring_entries, *s->cq_ring.ring_entries); else -- 2.25.1