sync engine: add support for pwritev/preadv
authorJens Axboe <axboe@kernel.dk>
Thu, 16 May 2013 18:36:57 +0000 (20:36 +0200)
committerJens Axboe <axboe@kernel.dk>
Thu, 16 May 2013 18:36:57 +0000 (20:36 +0200)
Signed-off-by: Jens Axboe <axboe@kernel.dk>
configure
engines/sync.c
options.c

index 5939bed7fec6316bc9c2b22cda6cd3ce364fdf63..95765cceffac57a203855a46941e6daa23d26482 100755 (executable)
--- a/configure
+++ b/configure
@@ -1066,6 +1066,23 @@ if compile_prog "" "" "RLIMIT_MEMLOCK"; then
 fi
 echo "RLIMIT_MEMLOCK                $rlimit_memlock"
 
 fi
 echo "RLIMIT_MEMLOCK                $rlimit_memlock"
 
+##########################################
+# Check whether we have pwritev/preadv
+pwritev="no"
+cat > $TMPC << EOF
+#include <stdio.h>
+#include <sys/uio.h>
+int main(int argc, char **argv)
+{
+  return pwritev(0, NULL, 1, 0) + preadv(0, NULL, 1, 0);
+}
+EOF
+if compile_prog "" "" "pwritev"; then
+  pwritev="yes"
+fi
+echo "pwritev/preadv                $pwritev"
+
+
 #############################################################################
 
 if test "$wordsize" = "64" ; then
 #############################################################################
 
 if test "$wordsize" = "64" ; then
@@ -1181,6 +1198,9 @@ fi
 if test "$rlimit_memlock" = "yes" ; then
   output_sym "CONFIG_RLIMIT_MEMLOCK"
 fi
 if test "$rlimit_memlock" = "yes" ; then
   output_sym "CONFIG_RLIMIT_MEMLOCK"
 fi
+if test "$pwritev" = "yes" ; then
+  output_sym "CONFIG_PWRITEV"
+fi
 
 echo "LIBS+=$LIBS" >> $config_host_mak
 echo "CFLAGS+=$CFLAGS" >> $config_host_mak
 
 echo "LIBS+=$LIBS" >> $config_host_mak
 echo "CFLAGS+=$CFLAGS" >> $config_host_mak
index 87796289dcc9ca0591e265d1eee83696bd2eb034..17714588030401e3b55b481be7ed9690e979cbd2 100644 (file)
@@ -69,6 +69,33 @@ static int fio_io_end(struct thread_data *td, struct io_u *io_u, int ret)
        return FIO_Q_COMPLETED;
 }
 
        return FIO_Q_COMPLETED;
 }
 
+#ifdef CONFIG_PWRITEV
+static int fio_pvsyncio_queue(struct thread_data *td, struct io_u *io_u)
+{
+       struct syncio_data *sd = td->io_ops->data;
+       struct iovec *iov = &sd->iovecs[0];
+       struct fio_file *f = io_u->file;
+       int ret;
+
+       fio_ro_check(td, io_u);
+
+       iov->iov_base = io_u->xfer_buf;
+       iov->iov_len = io_u->xfer_buflen;
+
+       if (io_u->ddir == DDIR_READ)
+               ret = preadv(f->fd, iov, 1, io_u->offset);
+       else if (io_u->ddir == DDIR_WRITE)
+               ret = pwritev(f->fd, iov, 1, io_u->offset);
+       else if (io_u->ddir == DDIR_TRIM) {
+               do_io_u_trim(td, io_u);
+               return FIO_Q_COMPLETED;
+       } else
+               ret = do_io_u_sync(td, io_u);
+
+       return fio_io_end(td, io_u, ret);
+}
+#endif
+
 static int fio_psyncio_queue(struct thread_data *td, struct io_u *io_u)
 {
        struct fio_file *f = io_u->file;
 static int fio_psyncio_queue(struct thread_data *td, struct io_u *io_u)
 {
        struct fio_file *f = io_u->file;
@@ -329,11 +356,26 @@ static struct ioengine_ops ioengine_vrw = {
        .flags          = FIO_SYNCIO,
 };
 
        .flags          = FIO_SYNCIO,
 };
 
+#ifdef CONFIG_PWRITEV
+static struct ioengine_ops ioengine_pvrw = {
+       .name           = "pvsync",
+       .version        = FIO_IOOPS_VERSION,
+       .init           = fio_vsyncio_init,
+       .cleanup        = fio_vsyncio_cleanup,
+       .queue          = fio_pvsyncio_queue,
+       .open_file      = generic_open_file,
+       .close_file     = generic_close_file,
+       .get_file_size  = generic_get_file_size,
+       .flags          = FIO_SYNCIO,
+};
+#endif
+
 static void fio_init fio_syncio_register(void)
 {
        register_ioengine(&ioengine_rw);
        register_ioengine(&ioengine_prw);
        register_ioengine(&ioengine_vrw);
 static void fio_init fio_syncio_register(void)
 {
        register_ioengine(&ioengine_rw);
        register_ioengine(&ioengine_prw);
        register_ioengine(&ioengine_vrw);
+       register_ioengine(&ioengine_pvrw);
 }
 
 static void fio_exit fio_syncio_unregister(void)
 }
 
 static void fio_exit fio_syncio_unregister(void)
@@ -341,4 +383,5 @@ static void fio_exit fio_syncio_unregister(void)
        unregister_ioengine(&ioengine_rw);
        unregister_ioengine(&ioengine_prw);
        unregister_ioengine(&ioengine_vrw);
        unregister_ioengine(&ioengine_rw);
        unregister_ioengine(&ioengine_prw);
        unregister_ioengine(&ioengine_vrw);
+       unregister_ioengine(&ioengine_pvrw);
 }
 }
index 7a4e7b5773c4fb675779addb179d0a8863a26400..e9df6a8ed0d7b2c6e6a60e8465a4ddcd6d924059 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1302,6 +1302,11 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                          { .ival = "vsync",
                            .help = "Use readv/writev",
                          },
                          { .ival = "vsync",
                            .help = "Use readv/writev",
                          },
+#ifdef CONFIG_PWRITEV
+                         { .ival = "pvsync",
+                           .help = "Use preadv/pwritev",
+                         },
+#endif
 #ifdef CONFIG_LIBAIO
                          { .ival = "libaio",
                            .help = "Linux native asynchronous IO",
 #ifdef CONFIG_LIBAIO
                          { .ival = "libaio",
                            .help = "Linux native asynchronous IO",