engines/io_uring: fix leak of 'ld' in error path
[fio.git] / engines / io_uring.c
1 /*
2  * io_uring engine
3  *
4  * IO engine using the new native Linux aio io_uring interface. See:
5  *
6  * http://git.kernel.dk/cgit/linux-block/log/?h=io_uring
7  *
8  */
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <errno.h>
12 #include <sys/time.h>
13 #include <sys/resource.h>
14
15 #include "../fio.h"
16 #include "../lib/pow2.h"
17 #include "../optgroup.h"
18 #include "../lib/memalign.h"
19 #include "../lib/fls.h"
20 #include "../lib/roundup.h"
21
22 #ifdef ARCH_HAVE_IOURING
23
24 #include "../lib/types.h"
25 #include "../os/linux/io_uring.h"
26 #include "cmdprio.h"
27 #include "zbd.h"
28 #include "nvme.h"
29
30 #include <sys/stat.h>
31
32 enum uring_cmd_type {
33         FIO_URING_CMD_NVME = 1,
34 };
35
36 struct io_sq_ring {
37         unsigned *head;
38         unsigned *tail;
39         unsigned *ring_mask;
40         unsigned *ring_entries;
41         unsigned *flags;
42         unsigned *array;
43 };
44
45 struct io_cq_ring {
46         unsigned *head;
47         unsigned *tail;
48         unsigned *ring_mask;
49         unsigned *ring_entries;
50         struct io_uring_cqe *cqes;
51 };
52
53 struct ioring_mmap {
54         void *ptr;
55         size_t len;
56 };
57
58 struct ioring_data {
59         int ring_fd;
60
61         struct io_u **io_u_index;
62         char *md_buf;
63
64         int *fds;
65
66         struct io_sq_ring sq_ring;
67         struct io_uring_sqe *sqes;
68         struct iovec *iovecs;
69         unsigned sq_ring_mask;
70
71         struct io_cq_ring cq_ring;
72         unsigned cq_ring_mask;
73
74         int queued;
75         int cq_ring_off;
76         unsigned iodepth;
77         int prepped;
78
79         struct ioring_mmap mmap[3];
80
81         struct cmdprio cmdprio;
82
83         struct nvme_dsm_range *dsm;
84 };
85
86 struct ioring_options {
87         struct thread_data *td;
88         unsigned int hipri;
89         struct cmdprio_options cmdprio_options;
90         unsigned int fixedbufs;
91         unsigned int registerfiles;
92         unsigned int sqpoll_thread;
93         unsigned int sqpoll_set;
94         unsigned int sqpoll_cpu;
95         unsigned int nonvectored;
96         unsigned int uncached;
97         unsigned int nowait;
98         unsigned int force_async;
99         unsigned int md_per_io_size;
100         unsigned int pi_act;
101         unsigned int apptag;
102         unsigned int apptag_mask;
103         unsigned int prchk;
104         char *pi_chk;
105         enum uring_cmd_type cmd_type;
106 };
107
108 static const int ddir_to_op[2][2] = {
109         { IORING_OP_READV, IORING_OP_READ },
110         { IORING_OP_WRITEV, IORING_OP_WRITE }
111 };
112
113 static const int fixed_ddir_to_op[2] = {
114         IORING_OP_READ_FIXED,
115         IORING_OP_WRITE_FIXED
116 };
117
118 static int fio_ioring_sqpoll_cb(void *data, unsigned long long *val)
119 {
120         struct ioring_options *o = data;
121
122         o->sqpoll_cpu = *val;
123         o->sqpoll_set = 1;
124         return 0;
125 }
126
127 static struct fio_option options[] = {
128         {
129                 .name   = "hipri",
130                 .lname  = "High Priority",
131                 .type   = FIO_OPT_STR_SET,
132                 .off1   = offsetof(struct ioring_options, hipri),
133                 .help   = "Use polled IO completions",
134                 .category = FIO_OPT_C_ENGINE,
135                 .group  = FIO_OPT_G_IOURING,
136         },
137         {
138                 .name   = "fixedbufs",
139                 .lname  = "Fixed (pre-mapped) IO buffers",
140                 .type   = FIO_OPT_STR_SET,
141                 .off1   = offsetof(struct ioring_options, fixedbufs),
142                 .help   = "Pre map IO buffers",
143                 .category = FIO_OPT_C_ENGINE,
144                 .group  = FIO_OPT_G_IOURING,
145         },
146         {
147                 .name   = "registerfiles",
148                 .lname  = "Register file set",
149                 .type   = FIO_OPT_STR_SET,
150                 .off1   = offsetof(struct ioring_options, registerfiles),
151                 .help   = "Pre-open/register files",
152                 .category = FIO_OPT_C_ENGINE,
153                 .group  = FIO_OPT_G_IOURING,
154         },
155         {
156                 .name   = "sqthread_poll",
157                 .lname  = "Kernel SQ thread polling",
158                 .type   = FIO_OPT_STR_SET,
159                 .off1   = offsetof(struct ioring_options, sqpoll_thread),
160                 .help   = "Offload submission/completion to kernel thread",
161                 .category = FIO_OPT_C_ENGINE,
162                 .group  = FIO_OPT_G_IOURING,
163         },
164         {
165                 .name   = "sqthread_poll_cpu",
166                 .lname  = "SQ Thread Poll CPU",
167                 .type   = FIO_OPT_INT,
168                 .cb     = fio_ioring_sqpoll_cb,
169                 .help   = "What CPU to run SQ thread polling on",
170                 .category = FIO_OPT_C_ENGINE,
171                 .group  = FIO_OPT_G_IOURING,
172         },
173         {
174                 .name   = "nonvectored",
175                 .lname  = "Non-vectored",
176                 .type   = FIO_OPT_INT,
177                 .off1   = offsetof(struct ioring_options, nonvectored),
178                 .def    = "-1",
179                 .help   = "Use non-vectored read/write commands",
180                 .category = FIO_OPT_C_ENGINE,
181                 .group  = FIO_OPT_G_IOURING,
182         },
183         {
184                 .name   = "uncached",
185                 .lname  = "Uncached",
186                 .type   = FIO_OPT_INT,
187                 .off1   = offsetof(struct ioring_options, uncached),
188                 .help   = "Use RWF_UNCACHED for buffered read/writes",
189                 .category = FIO_OPT_C_ENGINE,
190                 .group  = FIO_OPT_G_IOURING,
191         },
192         {
193                 .name   = "nowait",
194                 .lname  = "RWF_NOWAIT",
195                 .type   = FIO_OPT_BOOL,
196                 .off1   = offsetof(struct ioring_options, nowait),
197                 .help   = "Use RWF_NOWAIT for reads/writes",
198                 .category = FIO_OPT_C_ENGINE,
199                 .group  = FIO_OPT_G_IOURING,
200         },
201         {
202                 .name   = "force_async",
203                 .lname  = "Force async",
204                 .type   = FIO_OPT_INT,
205                 .off1   = offsetof(struct ioring_options, force_async),
206                 .help   = "Set IOSQE_ASYNC every N requests",
207                 .category = FIO_OPT_C_ENGINE,
208                 .group  = FIO_OPT_G_IOURING,
209         },
210         {
211                 .name   = "cmd_type",
212                 .lname  = "Uring cmd type",
213                 .type   = FIO_OPT_STR,
214                 .off1   = offsetof(struct ioring_options, cmd_type),
215                 .help   = "Specify uring-cmd type",
216                 .def    = "nvme",
217                 .posval = {
218                           { .ival = "nvme",
219                             .oval = FIO_URING_CMD_NVME,
220                             .help = "Issue nvme-uring-cmd",
221                           },
222                 },
223                 .category = FIO_OPT_C_ENGINE,
224                 .group  = FIO_OPT_G_IOURING,
225         },
226         CMDPRIO_OPTIONS(struct ioring_options, FIO_OPT_G_IOURING),
227         {
228                 .name   = "md_per_io_size",
229                 .lname  = "Separate Metadata Buffer Size per I/O",
230                 .type   = FIO_OPT_INT,
231                 .off1   = offsetof(struct ioring_options, md_per_io_size),
232                 .def    = "0",
233                 .help   = "Size of separate metadata buffer per I/O (Default: 0)",
234                 .category = FIO_OPT_C_ENGINE,
235                 .group  = FIO_OPT_G_IOURING,
236         },
237         {
238                 .name   = "pi_act",
239                 .lname  = "Protection Information Action",
240                 .type   = FIO_OPT_BOOL,
241                 .off1   = offsetof(struct ioring_options, pi_act),
242                 .def    = "1",
243                 .help   = "Protection Information Action bit (pi_act=1 or pi_act=0)",
244                 .category = FIO_OPT_C_ENGINE,
245                 .group  = FIO_OPT_G_IOURING,
246         },
247         {
248                 .name   = "pi_chk",
249                 .lname  = "Protection Information Check",
250                 .type   = FIO_OPT_STR_STORE,
251                 .off1   = offsetof(struct ioring_options, pi_chk),
252                 .def    = NULL,
253                 .help   = "Control of Protection Information Checking (pi_chk=GUARD,REFTAG,APPTAG)",
254                 .category = FIO_OPT_C_ENGINE,
255                 .group  = FIO_OPT_G_IOURING,
256         },
257         {
258                 .name   = "apptag",
259                 .lname  = "Application Tag used in Protection Information",
260                 .type   = FIO_OPT_INT,
261                 .off1   = offsetof(struct ioring_options, apptag),
262                 .def    = "0x1234",
263                 .help   = "Application Tag used in Protection Information field (Default: 0x1234)",
264                 .category = FIO_OPT_C_ENGINE,
265                 .group  = FIO_OPT_G_IOURING,
266         },
267         {
268                 .name   = "apptag_mask",
269                 .lname  = "Application Tag Mask",
270                 .type   = FIO_OPT_INT,
271                 .off1   = offsetof(struct ioring_options, apptag_mask),
272                 .def    = "0xffff",
273                 .help   = "Application Tag Mask used with Application Tag (Default: 0xffff)",
274                 .category = FIO_OPT_C_ENGINE,
275                 .group  = FIO_OPT_G_IOURING,
276         },
277         {
278                 .name   = NULL,
279         },
280 };
281
282 static int io_uring_enter(struct ioring_data *ld, unsigned int to_submit,
283                          unsigned int min_complete, unsigned int flags)
284 {
285 #ifdef FIO_ARCH_HAS_SYSCALL
286         return __do_syscall6(__NR_io_uring_enter, ld->ring_fd, to_submit,
287                                 min_complete, flags, NULL, 0);
288 #else
289         return syscall(__NR_io_uring_enter, ld->ring_fd, to_submit,
290                         min_complete, flags, NULL, 0);
291 #endif
292 }
293
294 static int fio_ioring_prep(struct thread_data *td, struct io_u *io_u)
295 {
296         struct ioring_data *ld = td->io_ops_data;
297         struct ioring_options *o = td->eo;
298         struct fio_file *f = io_u->file;
299         struct io_uring_sqe *sqe;
300
301         sqe = &ld->sqes[io_u->index];
302
303         if (o->registerfiles) {
304                 sqe->fd = f->engine_pos;
305                 sqe->flags = IOSQE_FIXED_FILE;
306         } else {
307                 sqe->fd = f->fd;
308                 sqe->flags = 0;
309         }
310
311         if (io_u->ddir == DDIR_READ || io_u->ddir == DDIR_WRITE) {
312                 if (o->fixedbufs) {
313                         sqe->opcode = fixed_ddir_to_op[io_u->ddir];
314                         sqe->addr = (unsigned long) io_u->xfer_buf;
315                         sqe->len = io_u->xfer_buflen;
316                         sqe->buf_index = io_u->index;
317                 } else {
318                         struct iovec *iov = &ld->iovecs[io_u->index];
319
320                         /*
321                          * Update based on actual io_u, requeue could have
322                          * adjusted these
323                          */
324                         iov->iov_base = io_u->xfer_buf;
325                         iov->iov_len = io_u->xfer_buflen;
326
327                         sqe->opcode = ddir_to_op[io_u->ddir][!!o->nonvectored];
328                         if (o->nonvectored) {
329                                 sqe->addr = (unsigned long) iov->iov_base;
330                                 sqe->len = iov->iov_len;
331                         } else {
332                                 sqe->addr = (unsigned long) iov;
333                                 sqe->len = 1;
334                         }
335                 }
336                 sqe->rw_flags = 0;
337                 if (!td->o.odirect && o->uncached)
338                         sqe->rw_flags |= RWF_UNCACHED;
339                 if (o->nowait)
340                         sqe->rw_flags |= RWF_NOWAIT;
341
342                 /*
343                  * Since io_uring can have a submission context (sqthread_poll)
344                  * that is different from the process context, we cannot rely on
345                  * the IO priority set by ioprio_set() (options prio, prioclass,
346                  * and priohint) to be inherited.
347                  * td->ioprio will have the value of the "default prio", so set
348                  * this unconditionally. This value might get overridden by
349                  * fio_ioring_cmdprio_prep() if the option cmdprio_percentage or
350                  * cmdprio_bssplit is used.
351                  */
352                 sqe->ioprio = td->ioprio;
353                 sqe->off = io_u->offset;
354         } else if (ddir_sync(io_u->ddir)) {
355                 sqe->ioprio = 0;
356                 if (io_u->ddir == DDIR_SYNC_FILE_RANGE) {
357                         sqe->off = f->first_write;
358                         sqe->len = f->last_write - f->first_write;
359                         sqe->sync_range_flags = td->o.sync_file_range;
360                         sqe->opcode = IORING_OP_SYNC_FILE_RANGE;
361                 } else {
362                         sqe->off = 0;
363                         sqe->addr = 0;
364                         sqe->len = 0;
365                         if (io_u->ddir == DDIR_DATASYNC)
366                                 sqe->fsync_flags |= IORING_FSYNC_DATASYNC;
367                         sqe->opcode = IORING_OP_FSYNC;
368                 }
369         }
370
371         if (o->force_async && ++ld->prepped == o->force_async) {
372                 ld->prepped = 0;
373                 sqe->flags |= IOSQE_ASYNC;
374         }
375
376         sqe->user_data = (unsigned long) io_u;
377         return 0;
378 }
379
380 static int fio_ioring_cmd_prep(struct thread_data *td, struct io_u *io_u)
381 {
382         struct ioring_data *ld = td->io_ops_data;
383         struct ioring_options *o = td->eo;
384         struct fio_file *f = io_u->file;
385         struct nvme_uring_cmd *cmd;
386         struct io_uring_sqe *sqe;
387
388         /* only supports nvme_uring_cmd */
389         if (o->cmd_type != FIO_URING_CMD_NVME)
390                 return -EINVAL;
391
392         if (io_u->ddir == DDIR_TRIM && td->io_ops->flags & FIO_ASYNCIO_SYNC_TRIM)
393                 return 0;
394
395         sqe = &ld->sqes[(io_u->index) << 1];
396
397         if (o->registerfiles) {
398                 sqe->fd = f->engine_pos;
399                 sqe->flags = IOSQE_FIXED_FILE;
400         } else {
401                 sqe->fd = f->fd;
402         }
403         sqe->rw_flags = 0;
404         if (!td->o.odirect && o->uncached)
405                 sqe->rw_flags |= RWF_UNCACHED;
406         if (o->nowait)
407                 sqe->rw_flags |= RWF_NOWAIT;
408
409         sqe->opcode = IORING_OP_URING_CMD;
410         sqe->user_data = (unsigned long) io_u;
411         if (o->nonvectored)
412                 sqe->cmd_op = NVME_URING_CMD_IO;
413         else
414                 sqe->cmd_op = NVME_URING_CMD_IO_VEC;
415         if (o->force_async && ++ld->prepped == o->force_async) {
416                 ld->prepped = 0;
417                 sqe->flags |= IOSQE_ASYNC;
418         }
419         if (o->fixedbufs) {
420                 sqe->uring_cmd_flags = IORING_URING_CMD_FIXED;
421                 sqe->buf_index = io_u->index;
422         }
423
424         cmd = (struct nvme_uring_cmd *)sqe->cmd;
425         return fio_nvme_uring_cmd_prep(cmd, io_u,
426                         o->nonvectored ? NULL : &ld->iovecs[io_u->index],
427                         &ld->dsm[io_u->index]);
428 }
429
430 static struct io_u *fio_ioring_event(struct thread_data *td, int event)
431 {
432         struct ioring_data *ld = td->io_ops_data;
433         struct io_uring_cqe *cqe;
434         struct io_u *io_u;
435         unsigned index;
436
437         index = (event + ld->cq_ring_off) & ld->cq_ring_mask;
438
439         cqe = &ld->cq_ring.cqes[index];
440         io_u = (struct io_u *) (uintptr_t) cqe->user_data;
441
442         if (cqe->res != io_u->xfer_buflen) {
443                 if (cqe->res > io_u->xfer_buflen)
444                         io_u->error = -cqe->res;
445                 else
446                         io_u->resid = io_u->xfer_buflen - cqe->res;
447         } else
448                 io_u->error = 0;
449
450         return io_u;
451 }
452
453 static struct io_u *fio_ioring_cmd_event(struct thread_data *td, int event)
454 {
455         struct ioring_data *ld = td->io_ops_data;
456         struct ioring_options *o = td->eo;
457         struct io_uring_cqe *cqe;
458         struct io_u *io_u;
459         struct nvme_data *data;
460         unsigned index;
461         int ret;
462
463         index = (event + ld->cq_ring_off) & ld->cq_ring_mask;
464         if (o->cmd_type == FIO_URING_CMD_NVME)
465                 index <<= 1;
466
467         cqe = &ld->cq_ring.cqes[index];
468         io_u = (struct io_u *) (uintptr_t) cqe->user_data;
469
470         if (cqe->res != 0)
471                 io_u->error = -cqe->res;
472         else
473                 io_u->error = 0;
474
475         if (o->cmd_type == FIO_URING_CMD_NVME) {
476                 data = FILE_ENG_DATA(io_u->file);
477                 if (data->pi_type && (io_u->ddir == DDIR_READ) && !o->pi_act) {
478                         ret = fio_nvme_pi_verify(data, io_u);
479                         if (ret)
480                                 io_u->error = ret;
481                 }
482         }
483
484         return io_u;
485 }
486
487 static int fio_ioring_cqring_reap(struct thread_data *td, unsigned int events,
488                                    unsigned int max)
489 {
490         struct ioring_data *ld = td->io_ops_data;
491         struct io_cq_ring *ring = &ld->cq_ring;
492         unsigned head, reaped = 0;
493
494         head = *ring->head;
495         do {
496                 if (head == atomic_load_acquire(ring->tail))
497                         break;
498                 reaped++;
499                 head++;
500         } while (reaped + events < max);
501
502         if (reaped)
503                 atomic_store_release(ring->head, head);
504
505         return reaped;
506 }
507
508 static int fio_ioring_getevents(struct thread_data *td, unsigned int min,
509                                 unsigned int max, const struct timespec *t)
510 {
511         struct ioring_data *ld = td->io_ops_data;
512         unsigned actual_min = td->o.iodepth_batch_complete_min == 0 ? 0 : min;
513         struct ioring_options *o = td->eo;
514         struct io_cq_ring *ring = &ld->cq_ring;
515         unsigned events = 0;
516         int r;
517
518         ld->cq_ring_off = *ring->head;
519         do {
520                 r = fio_ioring_cqring_reap(td, events, max);
521                 if (r) {
522                         events += r;
523                         max -= r;
524                         if (actual_min != 0)
525                                 actual_min -= r;
526                         continue;
527                 }
528
529                 if (!o->sqpoll_thread) {
530                         r = io_uring_enter(ld, 0, actual_min,
531                                                 IORING_ENTER_GETEVENTS);
532                         if (r < 0) {
533                                 if (errno == EAGAIN || errno == EINTR)
534                                         continue;
535                                 r = -errno;
536                                 td_verror(td, errno, "io_uring_enter");
537                                 break;
538                         }
539                 }
540         } while (events < min);
541
542         return r < 0 ? r : events;
543 }
544
545 static inline void fio_ioring_cmd_nvme_pi(struct thread_data *td,
546                                           struct io_u *io_u)
547 {
548         struct ioring_data *ld = td->io_ops_data;
549         struct ioring_options *o = td->eo;
550         struct nvme_uring_cmd *cmd;
551         struct io_uring_sqe *sqe;
552         struct nvme_cmd_ext_io_opts ext_opts = {0};
553         struct nvme_data *data = FILE_ENG_DATA(io_u->file);
554
555         if (io_u->ddir == DDIR_TRIM)
556                 return;
557
558         sqe = &ld->sqes[(io_u->index) << 1];
559         cmd = (struct nvme_uring_cmd *)sqe->cmd;
560
561         if (data->pi_type) {
562                 if (o->pi_act)
563                         ext_opts.io_flags |= NVME_IO_PRINFO_PRACT;
564                 ext_opts.io_flags |= o->prchk;
565                 ext_opts.apptag = o->apptag;
566                 ext_opts.apptag_mask = o->apptag_mask;
567         }
568
569         fio_nvme_pi_fill(cmd, io_u, &ext_opts);
570 }
571
572 static inline void fio_ioring_cmdprio_prep(struct thread_data *td,
573                                            struct io_u *io_u)
574 {
575         struct ioring_data *ld = td->io_ops_data;
576         struct cmdprio *cmdprio = &ld->cmdprio;
577
578         if (fio_cmdprio_set_ioprio(td, cmdprio, io_u))
579                 ld->sqes[io_u->index].ioprio = io_u->ioprio;
580 }
581
582 static enum fio_q_status fio_ioring_queue(struct thread_data *td,
583                                           struct io_u *io_u)
584 {
585         struct ioring_data *ld = td->io_ops_data;
586         struct ioring_options *o = td->eo;
587         struct io_sq_ring *ring = &ld->sq_ring;
588         unsigned tail, next_tail;
589
590         fio_ro_check(td, io_u);
591
592         if (ld->queued == ld->iodepth)
593                 return FIO_Q_BUSY;
594
595         if (io_u->ddir == DDIR_TRIM && td->io_ops->flags & FIO_ASYNCIO_SYNC_TRIM) {
596                 if (ld->queued)
597                         return FIO_Q_BUSY;
598
599                 do_io_u_trim(td, io_u);
600
601                 io_u_mark_submit(td, 1);
602                 io_u_mark_complete(td, 1);
603                 return FIO_Q_COMPLETED;
604         }
605
606         tail = *ring->tail;
607         next_tail = tail + 1;
608         if (next_tail == atomic_load_relaxed(ring->head))
609                 return FIO_Q_BUSY;
610
611         if (ld->cmdprio.mode != CMDPRIO_MODE_NONE)
612                 fio_ioring_cmdprio_prep(td, io_u);
613
614         if (!strcmp(td->io_ops->name, "io_uring_cmd") &&
615                 o->cmd_type == FIO_URING_CMD_NVME)
616                 fio_ioring_cmd_nvme_pi(td, io_u);
617
618         ring->array[tail & ld->sq_ring_mask] = io_u->index;
619         atomic_store_release(ring->tail, next_tail);
620
621         ld->queued++;
622         return FIO_Q_QUEUED;
623 }
624
625 static void fio_ioring_queued(struct thread_data *td, int start, int nr)
626 {
627         struct ioring_data *ld = td->io_ops_data;
628         struct timespec now;
629
630         if (!fio_fill_issue_time(td))
631                 return;
632
633         fio_gettime(&now, NULL);
634
635         while (nr--) {
636                 struct io_sq_ring *ring = &ld->sq_ring;
637                 int index = ring->array[start & ld->sq_ring_mask];
638                 struct io_u *io_u = ld->io_u_index[index];
639
640                 memcpy(&io_u->issue_time, &now, sizeof(now));
641                 io_u_queued(td, io_u);
642
643                 start++;
644         }
645
646         /*
647          * only used for iolog
648          */
649         if (td->o.read_iolog_file)
650                 memcpy(&td->last_issue, &now, sizeof(now));
651 }
652
653 static int fio_ioring_commit(struct thread_data *td)
654 {
655         struct ioring_data *ld = td->io_ops_data;
656         struct ioring_options *o = td->eo;
657         int ret;
658
659         if (!ld->queued)
660                 return 0;
661
662         /*
663          * Kernel side does submission. just need to check if the ring is
664          * flagged as needing a kick, if so, call io_uring_enter(). This
665          * only happens if we've been idle too long.
666          */
667         if (o->sqpoll_thread) {
668                 struct io_sq_ring *ring = &ld->sq_ring;
669                 unsigned start = *ld->sq_ring.tail - ld->queued;
670                 unsigned flags;
671
672                 flags = atomic_load_relaxed(ring->flags);
673                 if (flags & IORING_SQ_NEED_WAKEUP)
674                         io_uring_enter(ld, ld->queued, 0,
675                                         IORING_ENTER_SQ_WAKEUP);
676                 fio_ioring_queued(td, start, ld->queued);
677                 io_u_mark_submit(td, ld->queued);
678
679                 ld->queued = 0;
680                 return 0;
681         }
682
683         do {
684                 unsigned start = *ld->sq_ring.head;
685                 long nr = ld->queued;
686
687                 ret = io_uring_enter(ld, nr, 0, IORING_ENTER_GETEVENTS);
688                 if (ret > 0) {
689                         fio_ioring_queued(td, start, ret);
690                         io_u_mark_submit(td, ret);
691
692                         ld->queued -= ret;
693                         ret = 0;
694                 } else if (!ret) {
695                         io_u_mark_submit(td, ret);
696                         continue;
697                 } else {
698                         if (errno == EAGAIN || errno == EINTR) {
699                                 ret = fio_ioring_cqring_reap(td, 0, ld->queued);
700                                 if (ret)
701                                         continue;
702                                 /* Shouldn't happen */
703                                 usleep(1);
704                                 continue;
705                         }
706                         ret = -errno;
707                         td_verror(td, errno, "io_uring_enter submit");
708                         break;
709                 }
710         } while (ld->queued);
711
712         return ret;
713 }
714
715 static void fio_ioring_unmap(struct ioring_data *ld)
716 {
717         int i;
718
719         for (i = 0; i < FIO_ARRAY_SIZE(ld->mmap); i++)
720                 munmap(ld->mmap[i].ptr, ld->mmap[i].len);
721         close(ld->ring_fd);
722 }
723
724 static void fio_ioring_cleanup(struct thread_data *td)
725 {
726         struct ioring_data *ld = td->io_ops_data;
727
728         if (ld) {
729                 if (!(td->flags & TD_F_CHILD))
730                         fio_ioring_unmap(ld);
731
732                 fio_cmdprio_cleanup(&ld->cmdprio);
733                 free(ld->io_u_index);
734                 free(ld->md_buf);
735                 free(ld->iovecs);
736                 free(ld->fds);
737                 free(ld->dsm);
738                 free(ld);
739         }
740 }
741
742 static int fio_ioring_mmap(struct ioring_data *ld, struct io_uring_params *p)
743 {
744         struct io_sq_ring *sring = &ld->sq_ring;
745         struct io_cq_ring *cring = &ld->cq_ring;
746         void *ptr;
747
748         ld->mmap[0].len = p->sq_off.array + p->sq_entries * sizeof(__u32);
749         ptr = mmap(0, ld->mmap[0].len, PROT_READ | PROT_WRITE,
750                         MAP_SHARED | MAP_POPULATE, ld->ring_fd,
751                         IORING_OFF_SQ_RING);
752         ld->mmap[0].ptr = ptr;
753         sring->head = ptr + p->sq_off.head;
754         sring->tail = ptr + p->sq_off.tail;
755         sring->ring_mask = ptr + p->sq_off.ring_mask;
756         sring->ring_entries = ptr + p->sq_off.ring_entries;
757         sring->flags = ptr + p->sq_off.flags;
758         sring->array = ptr + p->sq_off.array;
759         ld->sq_ring_mask = *sring->ring_mask;
760
761         if (p->flags & IORING_SETUP_SQE128)
762                 ld->mmap[1].len = 2 * p->sq_entries * sizeof(struct io_uring_sqe);
763         else
764                 ld->mmap[1].len = p->sq_entries * sizeof(struct io_uring_sqe);
765         ld->sqes = mmap(0, ld->mmap[1].len, PROT_READ | PROT_WRITE,
766                                 MAP_SHARED | MAP_POPULATE, ld->ring_fd,
767                                 IORING_OFF_SQES);
768         ld->mmap[1].ptr = ld->sqes;
769
770         if (p->flags & IORING_SETUP_CQE32) {
771                 ld->mmap[2].len = p->cq_off.cqes +
772                                         2 * p->cq_entries * sizeof(struct io_uring_cqe);
773         } else {
774                 ld->mmap[2].len = p->cq_off.cqes +
775                                         p->cq_entries * sizeof(struct io_uring_cqe);
776         }
777         ptr = mmap(0, ld->mmap[2].len, PROT_READ | PROT_WRITE,
778                         MAP_SHARED | MAP_POPULATE, ld->ring_fd,
779                         IORING_OFF_CQ_RING);
780         ld->mmap[2].ptr = ptr;
781         cring->head = ptr + p->cq_off.head;
782         cring->tail = ptr + p->cq_off.tail;
783         cring->ring_mask = ptr + p->cq_off.ring_mask;
784         cring->ring_entries = ptr + p->cq_off.ring_entries;
785         cring->cqes = ptr + p->cq_off.cqes;
786         ld->cq_ring_mask = *cring->ring_mask;
787         return 0;
788 }
789
790 static void fio_ioring_probe(struct thread_data *td)
791 {
792         struct ioring_data *ld = td->io_ops_data;
793         struct ioring_options *o = td->eo;
794         struct io_uring_probe *p;
795         int ret;
796
797         /* already set by user, don't touch */
798         if (o->nonvectored != -1)
799                 return;
800
801         /* default to off, as that's always safe */
802         o->nonvectored = 0;
803
804         p = calloc(1, sizeof(*p) + 256 * sizeof(struct io_uring_probe_op));
805         if (!p)
806                 return;
807
808         ret = syscall(__NR_io_uring_register, ld->ring_fd,
809                         IORING_REGISTER_PROBE, p, 256);
810         if (ret < 0)
811                 goto out;
812
813         if (IORING_OP_WRITE > p->ops_len)
814                 goto out;
815
816         if ((p->ops[IORING_OP_READ].flags & IO_URING_OP_SUPPORTED) &&
817             (p->ops[IORING_OP_WRITE].flags & IO_URING_OP_SUPPORTED))
818                 o->nonvectored = 1;
819 out:
820         free(p);
821 }
822
823 static int fio_ioring_queue_init(struct thread_data *td)
824 {
825         struct ioring_data *ld = td->io_ops_data;
826         struct ioring_options *o = td->eo;
827         int depth = td->o.iodepth;
828         struct io_uring_params p;
829         int ret;
830
831         memset(&p, 0, sizeof(p));
832
833         if (o->hipri)
834                 p.flags |= IORING_SETUP_IOPOLL;
835         if (o->sqpoll_thread) {
836                 p.flags |= IORING_SETUP_SQPOLL;
837                 if (o->sqpoll_set) {
838                         p.flags |= IORING_SETUP_SQ_AFF;
839                         p.sq_thread_cpu = o->sqpoll_cpu;
840                 }
841
842                 /*
843                  * Submission latency for sqpoll_thread is just the time it
844                  * takes to fill in the SQ ring entries, and any syscall if
845                  * IORING_SQ_NEED_WAKEUP is set, we don't need to log that time
846                  * separately.
847                  */
848                 td->o.disable_slat = 1;
849         }
850
851         /*
852          * Clamp CQ ring size at our SQ ring size, we don't need more entries
853          * than that.
854          */
855         p.flags |= IORING_SETUP_CQSIZE;
856         p.cq_entries = depth;
857
858         /*
859          * Setup COOP_TASKRUN as we don't need to get IPI interrupted for
860          * completing IO operations.
861          */
862         p.flags |= IORING_SETUP_COOP_TASKRUN;
863
864         /*
865          * io_uring is always a single issuer, and we can defer task_work
866          * runs until we reap events.
867          */
868         p.flags |= IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN;
869
870 retry:
871         ret = syscall(__NR_io_uring_setup, depth, &p);
872         if (ret < 0) {
873                 if (errno == EINVAL && p.flags & IORING_SETUP_DEFER_TASKRUN) {
874                         p.flags &= ~IORING_SETUP_DEFER_TASKRUN;
875                         p.flags &= ~IORING_SETUP_SINGLE_ISSUER;
876                         goto retry;
877                 }
878                 if (errno == EINVAL && p.flags & IORING_SETUP_COOP_TASKRUN) {
879                         p.flags &= ~IORING_SETUP_COOP_TASKRUN;
880                         goto retry;
881                 }
882                 if (errno == EINVAL && p.flags & IORING_SETUP_CQSIZE) {
883                         p.flags &= ~IORING_SETUP_CQSIZE;
884                         goto retry;
885                 }
886                 return ret;
887         }
888
889         ld->ring_fd = ret;
890
891         fio_ioring_probe(td);
892
893         if (o->fixedbufs) {
894                 ret = syscall(__NR_io_uring_register, ld->ring_fd,
895                                 IORING_REGISTER_BUFFERS, ld->iovecs, depth);
896                 if (ret < 0)
897                         return ret;
898         }
899
900         return fio_ioring_mmap(ld, &p);
901 }
902
903 static int fio_ioring_cmd_queue_init(struct thread_data *td)
904 {
905         struct ioring_data *ld = td->io_ops_data;
906         struct ioring_options *o = td->eo;
907         int depth = td->o.iodepth;
908         struct io_uring_params p;
909         int ret;
910
911         memset(&p, 0, sizeof(p));
912
913         if (o->hipri)
914                 p.flags |= IORING_SETUP_IOPOLL;
915         if (o->sqpoll_thread) {
916                 p.flags |= IORING_SETUP_SQPOLL;
917                 if (o->sqpoll_set) {
918                         p.flags |= IORING_SETUP_SQ_AFF;
919                         p.sq_thread_cpu = o->sqpoll_cpu;
920                 }
921
922                 /*
923                  * Submission latency for sqpoll_thread is just the time it
924                  * takes to fill in the SQ ring entries, and any syscall if
925                  * IORING_SQ_NEED_WAKEUP is set, we don't need to log that time
926                  * separately.
927                  */
928                 td->o.disable_slat = 1;
929         }
930         if (o->cmd_type == FIO_URING_CMD_NVME) {
931                 p.flags |= IORING_SETUP_SQE128;
932                 p.flags |= IORING_SETUP_CQE32;
933         }
934
935         /*
936          * Clamp CQ ring size at our SQ ring size, we don't need more entries
937          * than that.
938          */
939         p.flags |= IORING_SETUP_CQSIZE;
940         p.cq_entries = depth;
941
942         /*
943          * Setup COOP_TASKRUN as we don't need to get IPI interrupted for
944          * completing IO operations.
945          */
946         p.flags |= IORING_SETUP_COOP_TASKRUN;
947
948         /*
949          * io_uring is always a single issuer, and we can defer task_work
950          * runs until we reap events.
951          */
952         p.flags |= IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN;
953
954 retry:
955         ret = syscall(__NR_io_uring_setup, depth, &p);
956         if (ret < 0) {
957                 if (errno == EINVAL && p.flags & IORING_SETUP_DEFER_TASKRUN) {
958                         p.flags &= ~IORING_SETUP_DEFER_TASKRUN;
959                         p.flags &= ~IORING_SETUP_SINGLE_ISSUER;
960                         goto retry;
961                 }
962                 if (errno == EINVAL && p.flags & IORING_SETUP_COOP_TASKRUN) {
963                         p.flags &= ~IORING_SETUP_COOP_TASKRUN;
964                         goto retry;
965                 }
966                 if (errno == EINVAL && p.flags & IORING_SETUP_CQSIZE) {
967                         p.flags &= ~IORING_SETUP_CQSIZE;
968                         goto retry;
969                 }
970                 return ret;
971         }
972
973         ld->ring_fd = ret;
974
975         fio_ioring_probe(td);
976
977         if (o->fixedbufs) {
978                 ret = syscall(__NR_io_uring_register, ld->ring_fd,
979                                 IORING_REGISTER_BUFFERS, ld->iovecs, depth);
980                 if (ret < 0)
981                         return ret;
982         }
983
984         return fio_ioring_mmap(ld, &p);
985 }
986
987 static int fio_ioring_register_files(struct thread_data *td)
988 {
989         struct ioring_data *ld = td->io_ops_data;
990         struct fio_file *f;
991         unsigned int i;
992         int ret;
993
994         ld->fds = calloc(td->o.nr_files, sizeof(int));
995
996         for_each_file(td, f, i) {
997                 ret = generic_open_file(td, f);
998                 if (ret)
999                         goto err;
1000                 ld->fds[i] = f->fd;
1001                 f->engine_pos = i;
1002         }
1003
1004         ret = syscall(__NR_io_uring_register, ld->ring_fd,
1005                         IORING_REGISTER_FILES, ld->fds, td->o.nr_files);
1006         if (ret) {
1007 err:
1008                 free(ld->fds);
1009                 ld->fds = NULL;
1010         }
1011
1012         /*
1013          * Pretend the file is closed again, and really close it if we hit
1014          * an error.
1015          */
1016         for_each_file(td, f, i) {
1017                 if (ret) {
1018                         int fio_unused ret2;
1019                         ret2 = generic_close_file(td, f);
1020                 } else
1021                         f->fd = -1;
1022         }
1023
1024         return ret;
1025 }
1026
1027 static int fio_ioring_post_init(struct thread_data *td)
1028 {
1029         struct ioring_data *ld = td->io_ops_data;
1030         struct ioring_options *o = td->eo;
1031         struct io_u *io_u;
1032         int err, i;
1033
1034         for (i = 0; i < td->o.iodepth; i++) {
1035                 struct iovec *iov = &ld->iovecs[i];
1036
1037                 io_u = ld->io_u_index[i];
1038                 iov->iov_base = io_u->buf;
1039                 iov->iov_len = td_max_bs(td);
1040         }
1041
1042         err = fio_ioring_queue_init(td);
1043         if (err) {
1044                 int init_err = errno;
1045
1046                 if (init_err == ENOSYS)
1047                         log_err("fio: your kernel doesn't support io_uring\n");
1048                 td_verror(td, init_err, "io_queue_init");
1049                 return 1;
1050         }
1051
1052         for (i = 0; i < td->o.iodepth; i++) {
1053                 struct io_uring_sqe *sqe;
1054
1055                 sqe = &ld->sqes[i];
1056                 memset(sqe, 0, sizeof(*sqe));
1057         }
1058
1059         if (o->registerfiles) {
1060                 err = fio_ioring_register_files(td);
1061                 if (err) {
1062                         td_verror(td, errno, "ioring_register_files");
1063                         return 1;
1064                 }
1065         }
1066
1067         return 0;
1068 }
1069
1070 static int fio_ioring_cmd_post_init(struct thread_data *td)
1071 {
1072         struct ioring_data *ld = td->io_ops_data;
1073         struct ioring_options *o = td->eo;
1074         struct io_u *io_u;
1075         int err, i;
1076
1077         for (i = 0; i < td->o.iodepth; i++) {
1078                 struct iovec *iov = &ld->iovecs[i];
1079
1080                 io_u = ld->io_u_index[i];
1081                 iov->iov_base = io_u->buf;
1082                 iov->iov_len = td_max_bs(td);
1083         }
1084
1085         err = fio_ioring_cmd_queue_init(td);
1086         if (err) {
1087                 int init_err = errno;
1088
1089                 td_verror(td, init_err, "io_queue_init");
1090                 return 1;
1091         }
1092
1093         for (i = 0; i < td->o.iodepth; i++) {
1094                 struct io_uring_sqe *sqe;
1095
1096                 if (o->cmd_type == FIO_URING_CMD_NVME) {
1097                         sqe = &ld->sqes[i << 1];
1098                         memset(sqe, 0, 2 * sizeof(*sqe));
1099                 } else {
1100                         sqe = &ld->sqes[i];
1101                         memset(sqe, 0, sizeof(*sqe));
1102                 }
1103         }
1104
1105         if (o->registerfiles) {
1106                 err = fio_ioring_register_files(td);
1107                 if (err) {
1108                         td_verror(td, errno, "ioring_register_files");
1109                         return 1;
1110                 }
1111         }
1112
1113         return 0;
1114 }
1115
1116 static void parse_prchk_flags(struct ioring_options *o)
1117 {
1118         if (!o->pi_chk)
1119                 return;
1120
1121         if (strstr(o->pi_chk, "GUARD") != NULL)
1122                 o->prchk = NVME_IO_PRINFO_PRCHK_GUARD;
1123         if (strstr(o->pi_chk, "REFTAG") != NULL)
1124                 o->prchk |= NVME_IO_PRINFO_PRCHK_REF;
1125         if (strstr(o->pi_chk, "APPTAG") != NULL)
1126                 o->prchk |= NVME_IO_PRINFO_PRCHK_APP;
1127 }
1128
1129 static int fio_ioring_init(struct thread_data *td)
1130 {
1131         struct ioring_options *o = td->eo;
1132         struct ioring_data *ld;
1133         unsigned long long md_size;
1134         int ret;
1135
1136         /* sqthread submission requires registered files */
1137         if (o->sqpoll_thread)
1138                 o->registerfiles = 1;
1139
1140         if (o->registerfiles && td->o.nr_files != td->o.open_files) {
1141                 log_err("fio: io_uring registered files require nr_files to "
1142                         "be identical to open_files\n");
1143                 return 1;
1144         }
1145
1146         ld = calloc(1, sizeof(*ld));
1147
1148         /* ring depth must be a power-of-2 */
1149         ld->iodepth = td->o.iodepth;
1150         td->o.iodepth = roundup_pow2(td->o.iodepth);
1151
1152         /* io_u index */
1153         ld->io_u_index = calloc(td->o.iodepth, sizeof(struct io_u *));
1154
1155         /*
1156          * metadata buffer for nvme command.
1157          * We are only supporting iomem=malloc / mem=malloc as of now.
1158          */
1159         if (!strcmp(td->io_ops->name, "io_uring_cmd") &&
1160             (o->cmd_type == FIO_URING_CMD_NVME) && o->md_per_io_size) {
1161                 md_size = (unsigned long long) o->md_per_io_size
1162                                 * (unsigned long long) td->o.iodepth;
1163                 md_size += page_mask + td->o.mem_align;
1164                 if (td->o.mem_align && td->o.mem_align > page_size)
1165                         md_size += td->o.mem_align - page_size;
1166                 if (td->o.mem_type == MEM_MALLOC) {
1167                         ld->md_buf = malloc(md_size);
1168                         if (!ld->md_buf) {
1169                                 free(ld);
1170                                 return 1;
1171                         }
1172                 } else {
1173                         log_err("fio: Only iomem=malloc or mem=malloc is supported\n");
1174                         free(ld);
1175                         return 1;
1176                 }
1177         }
1178         parse_prchk_flags(o);
1179
1180         ld->iovecs = calloc(td->o.iodepth, sizeof(struct iovec));
1181
1182         td->io_ops_data = ld;
1183
1184         ret = fio_cmdprio_init(td, &ld->cmdprio, &o->cmdprio_options);
1185         if (ret) {
1186                 td_verror(td, EINVAL, "fio_ioring_init");
1187                 return 1;
1188         }
1189
1190         /*
1191          * For io_uring_cmd, trims are async operations unless we are operating
1192          * in zbd mode where trim means zone reset.
1193          */
1194         if (!strcmp(td->io_ops->name, "io_uring_cmd") && td_trim(td) &&
1195             td->o.zone_mode == ZONE_MODE_ZBD)
1196                 td->io_ops->flags |= FIO_ASYNCIO_SYNC_TRIM;
1197         else
1198                 ld->dsm = calloc(ld->iodepth, sizeof(*ld->dsm));
1199
1200         return 0;
1201 }
1202
1203 static int fio_ioring_io_u_init(struct thread_data *td, struct io_u *io_u)
1204 {
1205         struct ioring_data *ld = td->io_ops_data;
1206         struct ioring_options *o = td->eo;
1207         struct nvme_pi_data *pi_data;
1208         char *p;
1209
1210         ld->io_u_index[io_u->index] = io_u;
1211
1212         if (!strcmp(td->io_ops->name, "io_uring_cmd")) {
1213                 p = PTR_ALIGN(ld->md_buf, page_mask) + td->o.mem_align;
1214                 p += o->md_per_io_size * io_u->index;
1215                 io_u->mmap_data = p;
1216
1217                 if (!o->pi_act) {
1218                         pi_data = calloc(1, sizeof(*pi_data));
1219                         pi_data->io_flags |= o->prchk;
1220                         pi_data->apptag_mask = o->apptag_mask;
1221                         pi_data->apptag = o->apptag;
1222                         io_u->engine_data = pi_data;
1223                 }
1224         }
1225
1226         return 0;
1227 }
1228
1229 static void fio_ioring_io_u_free(struct thread_data *td, struct io_u *io_u)
1230 {
1231         struct ioring_options *o = td->eo;
1232         struct nvme_pi *pi;
1233
1234         if (!strcmp(td->io_ops->name, "io_uring_cmd") &&
1235             (o->cmd_type == FIO_URING_CMD_NVME)) {
1236                 pi = io_u->engine_data;
1237                 free(pi);
1238                 io_u->engine_data = NULL;
1239         }
1240 }
1241
1242 static int fio_ioring_open_file(struct thread_data *td, struct fio_file *f)
1243 {
1244         struct ioring_data *ld = td->io_ops_data;
1245         struct ioring_options *o = td->eo;
1246
1247         if (!ld || !o->registerfiles)
1248                 return generic_open_file(td, f);
1249
1250         f->fd = ld->fds[f->engine_pos];
1251         return 0;
1252 }
1253
1254 static int fio_ioring_cmd_open_file(struct thread_data *td, struct fio_file *f)
1255 {
1256         struct ioring_data *ld = td->io_ops_data;
1257         struct ioring_options *o = td->eo;
1258
1259         if (o->cmd_type == FIO_URING_CMD_NVME) {
1260                 struct nvme_data *data = NULL;
1261                 unsigned int lba_size = 0;
1262                 __u64 nlba = 0;
1263                 int ret;
1264
1265                 /* Store the namespace-id and lba size. */
1266                 data = FILE_ENG_DATA(f);
1267                 if (data == NULL) {
1268                         data = calloc(1, sizeof(struct nvme_data));
1269                         ret = fio_nvme_get_info(f, &nlba, o->pi_act, data);
1270                         if (ret) {
1271                                 free(data);
1272                                 return ret;
1273                         }
1274
1275                         FILE_SET_ENG_DATA(f, data);
1276                 }
1277
1278                 lba_size = data->lba_ext ? data->lba_ext : data->lba_size;
1279
1280                 for_each_rw_ddir(ddir) {
1281                         if (td->o.min_bs[ddir] % lba_size ||
1282                                 td->o.max_bs[ddir] % lba_size) {
1283                                 if (data->lba_ext)
1284                                         log_err("%s: block size must be a multiple of (LBA data size + Metadata size)\n",
1285                                                 f->file_name);
1286                                 else
1287                                         log_err("%s: block size must be a multiple of LBA data size\n",
1288                                                 f->file_name);
1289                                 td_verror(td, EINVAL, "fio_ioring_cmd_open_file");
1290                                 return 1;
1291                         }
1292                         if (data->ms && !data->lba_ext && ddir != DDIR_TRIM &&
1293                             (o->md_per_io_size < ((td->o.max_bs[ddir] / data->lba_size) *
1294                                                   data->ms))) {
1295                                 log_err("%s: md_per_io_size should be at least %llu bytes\n",
1296                                         f->file_name,
1297                                         ((td->o.max_bs[ddir] / data->lba_size) * data->ms));
1298                                 td_verror(td, EINVAL, "fio_ioring_cmd_open_file");
1299                                 return 1;
1300                         }
1301                 }
1302         }
1303         if (!ld || !o->registerfiles)
1304                 return generic_open_file(td, f);
1305
1306         f->fd = ld->fds[f->engine_pos];
1307         return 0;
1308 }
1309
1310 static int fio_ioring_close_file(struct thread_data *td, struct fio_file *f)
1311 {
1312         struct ioring_data *ld = td->io_ops_data;
1313         struct ioring_options *o = td->eo;
1314
1315         if (!ld || !o->registerfiles)
1316                 return generic_close_file(td, f);
1317
1318         f->fd = -1;
1319         return 0;
1320 }
1321
1322 static int fio_ioring_cmd_close_file(struct thread_data *td,
1323                                      struct fio_file *f)
1324 {
1325         struct ioring_data *ld = td->io_ops_data;
1326         struct ioring_options *o = td->eo;
1327
1328         if (o->cmd_type == FIO_URING_CMD_NVME) {
1329                 struct nvme_data *data = FILE_ENG_DATA(f);
1330
1331                 FILE_SET_ENG_DATA(f, NULL);
1332                 free(data);
1333         }
1334         if (!ld || !o->registerfiles)
1335                 return generic_close_file(td, f);
1336
1337         f->fd = -1;
1338         return 0;
1339 }
1340
1341 static int fio_ioring_cmd_get_file_size(struct thread_data *td,
1342                                         struct fio_file *f)
1343 {
1344         struct ioring_options *o = td->eo;
1345
1346         if (fio_file_size_known(f))
1347                 return 0;
1348
1349         if (o->cmd_type == FIO_URING_CMD_NVME) {
1350                 struct nvme_data *data = NULL;
1351                 __u64 nlba = 0;
1352                 int ret;
1353
1354                 data = calloc(1, sizeof(struct nvme_data));
1355                 ret = fio_nvme_get_info(f, &nlba, o->pi_act, data);
1356                 if (ret) {
1357                         free(data);
1358                         return ret;
1359                 }
1360
1361                 f->real_file_size = data->lba_size * nlba;
1362                 fio_file_set_size_known(f);
1363
1364                 FILE_SET_ENG_DATA(f, data);
1365                 return 0;
1366         }
1367         return generic_get_file_size(td, f);
1368 }
1369
1370 static int fio_ioring_cmd_get_zoned_model(struct thread_data *td,
1371                                           struct fio_file *f,
1372                                           enum zbd_zoned_model *model)
1373 {
1374         return fio_nvme_get_zoned_model(td, f, model);
1375 }
1376
1377 static int fio_ioring_cmd_report_zones(struct thread_data *td,
1378                                        struct fio_file *f, uint64_t offset,
1379                                        struct zbd_zone *zbdz,
1380                                        unsigned int nr_zones)
1381 {
1382         return fio_nvme_report_zones(td, f, offset, zbdz, nr_zones);
1383 }
1384
1385 static int fio_ioring_cmd_reset_wp(struct thread_data *td, struct fio_file *f,
1386                                    uint64_t offset, uint64_t length)
1387 {
1388         return fio_nvme_reset_wp(td, f, offset, length);
1389 }
1390
1391 static int fio_ioring_cmd_get_max_open_zones(struct thread_data *td,
1392                                              struct fio_file *f,
1393                                              unsigned int *max_open_zones)
1394 {
1395         return fio_nvme_get_max_open_zones(td, f, max_open_zones);
1396 }
1397
1398 static int fio_ioring_cmd_fetch_ruhs(struct thread_data *td, struct fio_file *f,
1399                                      struct fio_ruhs_info *fruhs_info)
1400 {
1401         struct nvme_fdp_ruh_status *ruhs;
1402         int bytes, ret, i;
1403
1404         bytes = sizeof(*ruhs) + FDP_MAX_RUHS * sizeof(struct nvme_fdp_ruh_status_desc);
1405         ruhs = scalloc(1, bytes);
1406         if (!ruhs)
1407                 return -ENOMEM;
1408
1409         ret = fio_nvme_iomgmt_ruhs(td, f, ruhs, bytes);
1410         if (ret)
1411                 goto free;
1412
1413         fruhs_info->nr_ruhs = le16_to_cpu(ruhs->nruhsd);
1414         for (i = 0; i < fruhs_info->nr_ruhs; i++)
1415                 fruhs_info->plis[i] = le16_to_cpu(ruhs->ruhss[i].pid);
1416 free:
1417         sfree(ruhs);
1418         return ret;
1419 }
1420
1421 static struct ioengine_ops ioengine_uring = {
1422         .name                   = "io_uring",
1423         .version                = FIO_IOOPS_VERSION,
1424         .flags                  = FIO_ASYNCIO_SYNC_TRIM | FIO_NO_OFFLOAD |
1425                                         FIO_ASYNCIO_SETS_ISSUE_TIME,
1426         .init                   = fio_ioring_init,
1427         .post_init              = fio_ioring_post_init,
1428         .io_u_init              = fio_ioring_io_u_init,
1429         .prep                   = fio_ioring_prep,
1430         .queue                  = fio_ioring_queue,
1431         .commit                 = fio_ioring_commit,
1432         .getevents              = fio_ioring_getevents,
1433         .event                  = fio_ioring_event,
1434         .cleanup                = fio_ioring_cleanup,
1435         .open_file              = fio_ioring_open_file,
1436         .close_file             = fio_ioring_close_file,
1437         .get_file_size          = generic_get_file_size,
1438         .options                = options,
1439         .option_struct_size     = sizeof(struct ioring_options),
1440 };
1441
1442 static struct ioengine_ops ioengine_uring_cmd = {
1443         .name                   = "io_uring_cmd",
1444         .version                = FIO_IOOPS_VERSION,
1445         .flags                  = FIO_NO_OFFLOAD | FIO_MEMALIGN | FIO_RAWIO |
1446                                         FIO_ASYNCIO_SETS_ISSUE_TIME,
1447         .init                   = fio_ioring_init,
1448         .post_init              = fio_ioring_cmd_post_init,
1449         .io_u_init              = fio_ioring_io_u_init,
1450         .io_u_free              = fio_ioring_io_u_free,
1451         .prep                   = fio_ioring_cmd_prep,
1452         .queue                  = fio_ioring_queue,
1453         .commit                 = fio_ioring_commit,
1454         .getevents              = fio_ioring_getevents,
1455         .event                  = fio_ioring_cmd_event,
1456         .cleanup                = fio_ioring_cleanup,
1457         .open_file              = fio_ioring_cmd_open_file,
1458         .close_file             = fio_ioring_cmd_close_file,
1459         .get_file_size          = fio_ioring_cmd_get_file_size,
1460         .get_zoned_model        = fio_ioring_cmd_get_zoned_model,
1461         .report_zones           = fio_ioring_cmd_report_zones,
1462         .reset_wp               = fio_ioring_cmd_reset_wp,
1463         .get_max_open_zones     = fio_ioring_cmd_get_max_open_zones,
1464         .options                = options,
1465         .option_struct_size     = sizeof(struct ioring_options),
1466         .fdp_fetch_ruhs         = fio_ioring_cmd_fetch_ruhs,
1467 };
1468
1469 static void fio_init fio_ioring_register(void)
1470 {
1471         register_ioengine(&ioengine_uring);
1472         register_ioengine(&ioengine_uring_cmd);
1473 }
1474
1475 static void fio_exit fio_ioring_unregister(void)
1476 {
1477         unregister_ioengine(&ioengine_uring);
1478         unregister_ioengine(&ioengine_uring_cmd);
1479 }
1480 #endif