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