Only build t/read-to-pipe-async if pread() is available
[fio.git] / engines / io_uring.c
index 65f8e2361cbda824b8efe97aae009e6dae169f4d..7c19294be7582cf50fac87d67e0338aa196a5849 100644 (file)
@@ -75,6 +75,13 @@ struct ioring_options {
        unsigned int sqpoll_thread;
        unsigned int sqpoll_set;
        unsigned int sqpoll_cpu;
+       unsigned int nonvectored;
+       unsigned int uncached;
+};
+
+static const int ddir_to_op[2][2] = {
+       { IORING_OP_READV, IORING_OP_READ },
+       { IORING_OP_WRITEV, IORING_OP_WRITE }
 };
 
 static int fio_ioring_sqpoll_cb(void *data, unsigned long long *val)
@@ -132,6 +139,24 @@ static struct fio_option options[] = {
                .category = FIO_OPT_C_ENGINE,
                .group  = FIO_OPT_G_IOURING,
        },
+       {
+               .name   = "nonvectored",
+               .lname  = "Non-vectored",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct ioring_options, nonvectored),
+               .help   = "Use non-vectored read/write commands",
+               .category = FIO_OPT_C_ENGINE,
+               .group  = FIO_OPT_G_IOURING,
+       },
+       {
+               .name   = "uncached",
+               .lname  = "Uncached",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct ioring_options, uncached),
+               .help   = "Use RWF_UNCACHED for buffered read/writes",
+               .category = FIO_OPT_C_ENGINE,
+               .group  = FIO_OPT_G_IOURING,
+       },
        {
                .name   = NULL,
        },
@@ -152,39 +177,47 @@ static int fio_ioring_prep(struct thread_data *td, struct io_u *io_u)
        struct io_uring_sqe *sqe;
 
        sqe = &ld->sqes[io_u->index];
+
+       /* zero out fields not used in this submission */
+       memset(sqe, 0, sizeof(*sqe));
+
        if (o->registerfiles) {
                sqe->fd = f->engine_pos;
                sqe->flags = IOSQE_FIXED_FILE;
        } else {
                sqe->fd = f->fd;
-               sqe->flags = 0;
        }
-       sqe->ioprio = 0;
-       sqe->buf_index = 0;
 
        if (io_u->ddir == DDIR_READ || io_u->ddir == DDIR_WRITE) {
+               sqe->opcode = ddir_to_op[io_u->ddir][!!o->nonvectored];
                if (o->fixedbufs) {
-                       if (io_u->ddir == DDIR_READ)
-                               sqe->opcode = IORING_OP_READ_FIXED;
-                       else
-                               sqe->opcode = IORING_OP_WRITE_FIXED;
                        sqe->addr = (unsigned long) io_u->xfer_buf;
                        sqe->len = io_u->xfer_buflen;
                        sqe->buf_index = io_u->index;
                } else {
-                       if (io_u->ddir == DDIR_READ)
-                               sqe->opcode = IORING_OP_READV;
-                       else
-                               sqe->opcode = IORING_OP_WRITEV;
-                       sqe->addr = (unsigned long) &ld->iovecs[io_u->index];
-                       sqe->len = 1;
+                       if (o->nonvectored) {
+                               sqe->addr = (unsigned long)
+                                               ld->iovecs[io_u->index].iov_base;
+                               sqe->len = ld->iovecs[io_u->index].iov_len;
+                       } else {
+                               sqe->addr = (unsigned long) &ld->iovecs[io_u->index];
+                               sqe->len = 1;
+                       }
                }
+               if (!td->o.odirect && o->uncached)
+                       sqe->rw_flags = RWF_UNCACHED;
                sqe->off = io_u->offset;
        } else if (ddir_sync(io_u->ddir)) {
-               sqe->fsync_flags = 0;
-               if (io_u->ddir == DDIR_DATASYNC)
-                       sqe->fsync_flags |= IORING_FSYNC_DATASYNC;
-               sqe->opcode = IORING_OP_FSYNC;
+               if (io_u->ddir == DDIR_SYNC_FILE_RANGE) {
+                       sqe->off = f->first_write;
+                       sqe->len = f->last_write - f->first_write;
+                       sqe->sync_range_flags = td->o.sync_file_range;
+                       sqe->opcode = IORING_OP_SYNC_FILE_RANGE;
+               } else {
+                       if (io_u->ddir == DDIR_DATASYNC)
+                               sqe->fsync_flags |= IORING_FSYNC_DATASYNC;
+                       sqe->opcode = IORING_OP_FSYNC;
+               }
        }
 
        sqe->user_data = (unsigned long) io_u;
@@ -259,7 +292,7 @@ static int fio_ioring_getevents(struct thread_data *td, unsigned int min,
                        r = io_uring_enter(ld, 0, actual_min,
                                                IORING_ENTER_GETEVENTS);
                        if (r < 0) {
-                               if (errno == EAGAIN)
+                               if (errno == EAGAIN || errno == EINTR)
                                        continue;
                                td_verror(td, errno, "io_uring_enter");
                                break;
@@ -370,7 +403,7 @@ static int fio_ioring_commit(struct thread_data *td)
                        io_u_mark_submit(td, ret);
                        continue;
                } else {
-                       if (errno == EAGAIN) {
+                       if (errno == EAGAIN || errno == EINTR) {
                                ret = fio_ioring_cqring_reap(td, 0, ld->queued);
                                if (ret)
                                        continue;
@@ -555,7 +588,6 @@ static int fio_ioring_post_init(struct thread_data *td)
                return 1;
        }
 
-       printf("files=%d\n", o->registerfiles);
        if (o->registerfiles) {
                err = fio_ioring_register_files(td);
                if (err) {