From 81887d5dcd608492e59ed3fb2ac8fcb463223120 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 7 Sep 2007 20:36:08 +0200 Subject: [PATCH] splice: update to new vmsplice-to-user interface I changed the kernel bits (they aren't merged yet), so update the fio splice engine to reflect that. Signed-off-by: Jens Axboe --- engines/splice.c | 69 ++++++++++++++++++++++++++++++------------------ fio.h | 6 +---- io_u.c | 2 -- os/os-linux.h | 4 --- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/engines/splice.c b/engines/splice.c index 1cce513b..440196b8 100644 --- a/engines/splice.c +++ b/engines/splice.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "../fio.h" @@ -66,17 +67,6 @@ static int fio_splice_read_old(struct thread_data *td, struct io_u *io_u) return io_u->xfer_buflen; } -static void splice_unmap_io_u(struct thread_data *td, struct io_u *io_u) -{ - struct spliceio_data *sd = td->io_ops->data; - struct iovec iov = { - .iov_base = io_u->xfer_buf, - .iov_len = io_u->xfer_buflen, - }; - - vmsplice(sd->pipe[0], &iov, 1, SPLICE_F_UNMAP); -} - /* * We can now vmsplice into userspace, so do the transfer by splicing into * a pipe and vmsplicing that into userspace. @@ -86,26 +76,36 @@ static int fio_splice_read(struct thread_data *td, struct io_u *io_u) struct spliceio_data *sd = td->io_ops->data; struct fio_file *f = io_u->file; struct iovec iov; - int ret, buflen; + int ret = 0 , buflen, mmap_len; off_t offset; - void *p; + void *p, *map; offset = io_u->offset; - buflen = io_u->xfer_buflen; - p = io_u->xfer_buf; - io_u->xfer_buf = NULL; + mmap_len = buflen = io_u->xfer_buflen; + + map = mmap(io_u->xfer_buf, buflen, PROT_READ, MAP_PRIVATE|OS_MAP_ANON, 0, 0); + if (map == MAP_FAILED) { + td_verror(td, errno, "mmap io_u"); + return -1; + } + + p = map; while (buflen) { int this_len = buflen; + int flags = 0; - if (this_len > SPLICE_DEF_SIZE) + if (this_len > SPLICE_DEF_SIZE) { this_len = SPLICE_DEF_SIZE; + flags = SPLICE_F_MORE; + } - ret = splice(f->fd, &offset, sd->pipe[1], NULL, this_len, SPLICE_F_MORE); + ret = splice(f->fd, &offset, sd->pipe[1], NULL, this_len,flags); if (ret < 0) { if (errno == ENODATA || errno == EAGAIN) continue; - return -errno; + td_verror(td, errno, "splice-from-fd"); + break; } buflen -= ret; @@ -115,19 +115,29 @@ static int fio_splice_read(struct thread_data *td, struct io_u *io_u) while (iov.iov_len) { ret = vmsplice(sd->pipe[0], &iov, 1, SPLICE_F_MOVE); - if (ret < 0) - return -errno; - else if (!ret) - return -ENODATA; + if (ret < 0) { + td_verror(td, errno, "vmsplice"); + break; + } else if (!ret) { + td_verror(td, ENODATA, "vmsplice"); + ret = -1; + break; + } - if (!io_u->xfer_buf) - io_u->xfer_buf = iov.iov_base; iov.iov_len -= ret; iov.iov_base += ret; } + if (ret < 0) + break; + } + + if (munmap(map, mmap_len) < 0) { + td_verror(td, errno, "munnap io_u"); + return -1; } + if (ret < 0) + return ret; - io_u->unmap = splice_unmap_io_u; return io_u->xfer_buflen; } @@ -235,6 +245,13 @@ static int fio_spliceio_init(struct thread_data *td) */ sd->vmsplice_to_user = 1; + /* + * And if vmsplice_to_user works, we definitely need aligned + * buffers. Just set ->odirect to force that. + */ + if (td_read(td)) + td->o.odirect = 1; + td->io_ops->data = sd; return 0; } diff --git a/fio.h b/fio.h index fe314bfd..5177795c 100644 --- a/fio.h +++ b/fio.h @@ -175,11 +175,6 @@ struct io_u { * Callback for io completion */ int (*end_io)(struct thread_data *, struct io_u *); - - /* - * Called when io_u is about to be freed - */ - void (*unmap)(struct thread_data *, struct io_u *); }; /* @@ -375,6 +370,7 @@ struct thread_stat { unsigned long usr_time; unsigned long sys_time; unsigned long ctx; + unsigned long minf, majf; /* * IO depth and latency stats diff --git a/io_u.c b/io_u.c index 1a68ad11..4750ac60 100644 --- a/io_u.c +++ b/io_u.c @@ -770,8 +770,6 @@ static void io_completed(struct thread_data *td, struct io_u *io_u, if (ret && !icd->error) icd->error = ret; } - if (io_u->unmap) - io_u->unmap(td, io_u); } else { icd->error = io_u->error; io_u_log_error(td, io_u); diff --git a/os/os-linux.h b/os/os-linux.h index dd783be3..ed195537 100644 --- a/os/os-linux.h +++ b/os/os-linux.h @@ -98,10 +98,6 @@ static inline int vmsplice(int fd, const struct iovec *iov, } #endif -#ifndef SPLICE_F_UNMAP -#define SPLICE_F_UNMAP (0x10) -#endif - #define SPLICE_DEF_SIZE (64*1024) #ifdef FIO_HAVE_SYSLET -- 2.25.1