io_u: fall through to unlock path in case of error
[fio.git] / engines / libaio.c
index e0d7cbbafb780551f35c62c83bb9dd3b26b4b164..b241ed99c4972e9956597d355645c65fa8274498 100644 (file)
@@ -4,17 +4,18 @@
  * IO engine using the Linux native aio interface.
  *
  */
-#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
-#include <assert.h>
 #include <libaio.h>
 
 #include "../fio.h"
 #include "../lib/pow2.h"
 #include "../optgroup.h"
 
+#define IOCB_CMD_PREAD_POLL 9
+#define IOCB_CMD_PWRITE_POLL 10
+
 static int fio_libaio_commit(struct thread_data *td);
 
 struct libaio_data {
@@ -41,6 +42,7 @@ struct libaio_data {
 struct libaio_options {
        void *pad;
        unsigned int userspace_reap;
+       unsigned int hipri;
 };
 
 static struct fio_option options[] = {
@@ -53,6 +55,15 @@ static struct fio_option options[] = {
                .category = FIO_OPT_C_ENGINE,
                .group  = FIO_OPT_G_LIBAIO,
        },
+       {
+               .name   = "hipri",
+               .lname  = "RWF_HIPRI",
+               .type   = FIO_OPT_STR_SET,
+               .off1   = offsetof(struct libaio_options, hipri),
+               .help   = "Use polled IO completions",
+               .category = FIO_OPT_C_ENGINE,
+               .group  = FIO_OPT_G_LIBAIO,
+       },
        {
                .name   = NULL,
        },
@@ -70,12 +81,17 @@ static inline void ring_inc(struct libaio_data *ld, unsigned int *val,
 static int fio_libaio_prep(struct thread_data fio_unused *td, struct io_u *io_u)
 {
        struct fio_file *f = io_u->file;
+       struct libaio_options *o = td->eo;
 
-       if (io_u->ddir == DDIR_READ)
+       if (io_u->ddir == DDIR_READ) {
                io_prep_pread(&io_u->iocb, f->fd, io_u->xfer_buf, io_u->xfer_buflen, io_u->offset);
-       else if (io_u->ddir == DDIR_WRITE)
+               if (o->hipri)
+                       io_u->iocb.aio_lio_opcode = IOCB_CMD_PREAD_POLL;
+       } else if (io_u->ddir == DDIR_WRITE) {
                io_prep_pwrite(&io_u->iocb, f->fd, io_u->xfer_buf, io_u->xfer_buflen, io_u->offset);
-       else if (ddir_sync(io_u->ddir))
+               if (o->hipri)
+                       io_u->iocb.aio_lio_opcode = IOCB_CMD_PWRITE_POLL;
+       } else if (ddir_sync(io_u->ddir))
                io_prep_fsync(&io_u->iocb, f->fd);
 
        return 0;
@@ -171,7 +187,8 @@ static int fio_libaio_getevents(struct thread_data *td, unsigned int min,
                        events += r;
                else if ((min && r == 0) || r == -EAGAIN) {
                        fio_libaio_commit(td);
-                       usleep(100);
+                       if (actual_min)
+                               usleep(10);
                } else if (r != -EINTR)
                        break;
        } while (events < min);
@@ -179,7 +196,8 @@ static int fio_libaio_getevents(struct thread_data *td, unsigned int min,
        return r < 0 ? r : events;
 }
 
-static int fio_libaio_queue(struct thread_data *td, struct io_u *io_u)
+static enum fio_q_status fio_libaio_queue(struct thread_data *td,
+                                         struct io_u *io_u)
 {
        struct libaio_data *ld = td->io_ops_data;
 
@@ -207,6 +225,8 @@ static int fio_libaio_queue(struct thread_data *td, struct io_u *io_u)
                        return FIO_Q_BUSY;
 
                do_io_u_trim(td, io_u);
+               io_u_mark_submit(td, 1);
+               io_u_mark_complete(td, 1);
                return FIO_Q_COMPLETED;
        }