X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Fnet.c;h=552ad0bdb551abebb68f26571df5dc5e2ad20b8f;hp=bc3946d588f4c389d448ca4c3c36cb1d4c1d0b84;hb=7101d9c24abec4be58a086d85d6d92ec6e6492e9;hpb=4d94c275d2344b9231d9dc4585bd42b8e9fb7794 diff --git a/engines/net.c b/engines/net.c index bc3946d5..552ad0bd 100644 --- a/engines/net.c +++ b/engines/net.c @@ -52,18 +52,12 @@ static int fio_netio_prep(struct thread_data *td, struct io_u *io_u) return 1; } -/* - * Receive bytes from a socket and fill them into the internal pipe - */ -static int splice_in(struct thread_data *td, struct io_u *io_u) +static int splice_io_u(int fdin, int fdout, unsigned int len) { - struct netio_data *nd = td->io_ops->data; - unsigned int len = io_u->xfer_buflen; - struct fio_file *f = io_u->file; int bytes = 0; while (len) { - int ret = splice(f->fd, NULL, nd->pipes[1], NULL, len, 0); + int ret = splice(fdin, NULL, fdout, NULL, len, 0); if (ret < 0) { if (!bytes) @@ -81,40 +75,28 @@ static int splice_in(struct thread_data *td, struct io_u *io_u) } /* - * Transmit 'len' bytes from the internal pipe + * Receive bytes from a socket and fill them into the internal pipe */ -static int splice_out(struct thread_data *td, struct io_u *io_u, - unsigned int len) +static int splice_in(struct thread_data *td, struct io_u *io_u) { struct netio_data *nd = td->io_ops->data; - struct fio_file *f = io_u->file; - int bytes = 0; - - while (len) { - int ret = splice(nd->pipes[0], NULL, f->fd, NULL, len, 0); - - if (ret < 0) { - if (!bytes) - bytes = ret; - - break; - } else if (!ret) - break; - - bytes += ret; - len -= ret; - } - return bytes; + return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen); } /* - * vmsplice() pipe to io_u buffer + * Transmit 'len' bytes from the internal pipe */ -static int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, - unsigned int len) +static int splice_out(struct thread_data *td, struct io_u *io_u, + unsigned int len) { struct netio_data *nd = td->io_ops->data; + + return splice_io_u(nd->pipes[0], io_u->file->fd, len); +} + +static int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len) +{ struct iovec iov = { .iov_base = io_u->xfer_buf, .iov_len = len, @@ -122,7 +104,7 @@ static int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, int bytes = 0; while (iov.iov_len) { - int ret = vmsplice(nd->pipes[0], &iov, 1, SPLICE_F_MOVE); + int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE); if (ret < 0) { if (!bytes) @@ -132,63 +114,63 @@ static int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, break; iov.iov_len -= ret; + iov.iov_base += ret; bytes += ret; - if (iov.iov_len) - iov.iov_base += ret; } return bytes; + } /* - * vmsplice() io_u to pipe + * vmsplice() pipe to io_u buffer */ -static int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u) +static int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, + unsigned int len) { struct netio_data *nd = td->io_ops->data; - struct iovec iov = { - .iov_base = io_u->xfer_buf, - .iov_len = io_u->xfer_buflen, - }; - unsigned int bytes = 0; - - while (iov.iov_len) { - int ret = vmsplice(nd->pipes[1], &iov, 1, SPLICE_F_MOVE); - if (ret < 0) - return -1; - else if (!ret) - return bytes; + return vmsplice_io_u(io_u, nd->pipes[0], len); +} - iov.iov_len -= ret; - bytes += ret; - if (iov.iov_len) - iov.iov_base += ret; - } +/* + * vmsplice() io_u to pipe + */ +static int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u) +{ + struct netio_data *nd = td->io_ops->data; - return bytes; + return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen); } +/* + * splice receive - transfer socket data into a pipe using splice, then map + * that pipe data into the io_u using vmsplice. + */ static int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u) { int ret; ret = splice_in(td, io_u); - if (ret <= 0) - return ret; + if (ret > 0) + return vmsplice_io_u_out(td, io_u, ret); - return vmsplice_io_u_out(td, io_u, ret); + return ret; } +/* + * splice transmit - map data from the io_u into a pipe by using vmsplice, + * then transfer that pipe to a socket using splice. + */ static int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u) { int ret; ret = vmsplice_io_u_in(td, io_u); - if (ret <= 0) - return ret; + if (ret > 0) + return splice_out(td, io_u, ret); - return splice_out(td, io_u, ret); + return ret; } static int fio_netio_send(struct thread_data *td, struct io_u *io_u) @@ -216,6 +198,8 @@ static int fio_netio_queue(struct thread_data *td, struct io_u *io_u) struct netio_data *nd = td->io_ops->data; int ret; + fio_ro_check(td, io_u); + if (io_u->ddir == DDIR_WRITE) { if (nd->use_splice) ret = fio_netio_splice_out(td, io_u); @@ -306,7 +290,6 @@ static int fio_netio_accept(struct thread_data *td, struct fio_file *f) return 0; } - static int fio_netio_open_file(struct thread_data *td, struct fio_file *f) { if (td_read(td)) @@ -424,6 +407,13 @@ static void fio_netio_cleanup(struct thread_data *td) struct netio_data *nd = td->io_ops->data; if (nd) { + if (nd->listenfd != -1) + close(nd->listenfd); + if (nd->pipes[0] != -1) + close(nd->pipes[0]); + if (nd->pipes[1] != -1) + close(nd->pipes[1]); + free(nd); td->io_ops->data = NULL; } @@ -438,6 +428,7 @@ static int fio_netio_setup(struct thread_data *td) memset(nd, 0, sizeof(*nd)); nd->listenfd = -1; + nd->pipes[0] = nd->pipes[1] = -1; td->io_ops->data = nd; } @@ -472,7 +463,7 @@ static struct ioengine_ops ioengine_rw = { .cleanup = fio_netio_cleanup, .open_file = fio_netio_open_file, .close_file = generic_close_file, - .flags = FIO_SYNCIO | FIO_DISKLESSIO, + .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR, }; static struct ioengine_ops ioengine_splice = { @@ -485,7 +476,7 @@ static struct ioengine_ops ioengine_splice = { .cleanup = fio_netio_cleanup, .open_file = fio_netio_open_file, .close_file = generic_close_file, - .flags = FIO_SYNCIO | FIO_DISKLESSIO, + .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR, }; static void fio_init fio_netio_register(void)