X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=engines%2Fnet.c;h=ca6fb344b89786123e824dfa60eb913b4db33d6f;hb=c1f6f32ea74316df1e8707eba4fb95ab14fae6f7;hp=eb72e2eee389857346c22cbe376f1c0c7fe36c9a;hpb=e9ad9637d9a444132c23cdcf907e2adeb8f87b89;p=fio.git diff --git a/engines/net.c b/engines/net.c index eb72e2ee..ca6fb344 100644 --- a/engines/net.c +++ b/engines/net.c @@ -9,28 +9,27 @@ #include #include #include -#include #include #include #include #include -#include -#include +#include #include #include #include #include "../fio.h" #include "../verify.h" +#include "../optgroup.h" struct netio_data { int listenfd; int use_splice; + int seq_off; int pipes[2]; struct sockaddr_in addr; struct sockaddr_in6 addr6; struct sockaddr_un addr_un; - uint64_t udp_lost; uint64_t udp_send_seq; uint64_t udp_recv_seq; }; @@ -56,6 +55,7 @@ struct udp_close_msg { struct udp_seq { uint64_t magic; uint64_t seq; + uint64_t bs; }; enum { @@ -133,6 +133,7 @@ static struct fio_option options[] = { #ifdef CONFIG_TCP_NODELAY { .name = "nodelay", + .lname = "No Delay", .type = FIO_OPT_BOOL, .off1 = offsetof(struct netio_options, nodelay), .help = "Use TCP_NODELAY on TCP connections", @@ -151,6 +152,7 @@ static struct fio_option options[] = { }, { .name = "pingpong", + .lname = "Ping Pong", .type = FIO_OPT_STR_SET, .off1 = offsetof(struct netio_options, pingpong), .help = "Ping-pong IO requests", @@ -372,7 +374,7 @@ static int splice_io_u(int fdin, int fdout, 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 netio_data *nd = td->io_ops_data; return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen); } @@ -383,7 +385,7 @@ static int splice_in(struct thread_data *td, struct io_u *io_u) static int splice_out(struct thread_data *td, struct io_u *io_u, unsigned int len) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; return splice_io_u(nd->pipes[0], io_u->file->fd, len); } @@ -421,7 +423,7 @@ static int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len) 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 netio_data *nd = td->io_ops_data; return vmsplice_io_u(io_u, nd->pipes[0], len); } @@ -431,7 +433,7 @@ static int vmsplice_io_u_out(struct thread_data *td, struct io_u *io_u, */ static int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen); } @@ -483,31 +485,46 @@ static void store_udp_seq(struct netio_data *nd, struct io_u *io_u) { struct udp_seq *us; + if (io_u->xfer_buflen < sizeof(*us)) + return; + us = io_u->xfer_buf + io_u->xfer_buflen - sizeof(*us); - us->magic = cpu_to_le64(FIO_UDP_SEQ_MAGIC); + us->magic = cpu_to_le64((uint64_t) FIO_UDP_SEQ_MAGIC); + us->bs = cpu_to_le64((uint64_t) io_u->xfer_buflen); us->seq = cpu_to_le64(nd->udp_send_seq++); } -static void verify_udp_seq(struct netio_data *nd, struct io_u *io_u) +static void verify_udp_seq(struct thread_data *td, struct netio_data *nd, + struct io_u *io_u) { struct udp_seq *us; uint64_t seq; + if (io_u->xfer_buflen < sizeof(*us)) + return; + + if (nd->seq_off) + return; + us = io_u->xfer_buf + io_u->xfer_buflen - sizeof(*us); if (le64_to_cpu(us->magic) != FIO_UDP_SEQ_MAGIC) return; + if (le64_to_cpu(us->bs) != io_u->xfer_buflen) { + nd->seq_off = 1; + return; + } seq = le64_to_cpu(us->seq); if (seq != nd->udp_recv_seq) - nd->udp_lost += seq - nd->udp_recv_seq; + td->ts.drop_io_u[io_u->ddir] += seq - nd->udp_recv_seq; nd->udp_recv_seq = seq + 1; } static int fio_netio_send(struct thread_data *td, struct io_u *io_u) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; int ret, flags = 0; @@ -552,7 +569,7 @@ static int fio_netio_send(struct thread_data *td, struct io_u *io_u) return ret; } -static int is_udp_close(struct io_u *io_u, int len) +static int is_close_msg(struct io_u *io_u, int len) { struct udp_close_msg *msg; @@ -560,9 +577,9 @@ static int is_udp_close(struct io_u *io_u, int len) return 0; msg = io_u->xfer_buf; - if (ntohl(msg->magic) != FIO_LINK_OPEN_CLOSE_MAGIC) + if (le32_to_cpu(msg->magic) != FIO_LINK_OPEN_CLOSE_MAGIC) return 0; - if (ntohl(msg->cmd) != FIO_LINK_CLOSE) + if (le32_to_cpu(msg->cmd) != FIO_LINK_CLOSE) return 0; return 1; @@ -570,7 +587,7 @@ static int is_udp_close(struct io_u *io_u, int len) static int fio_netio_recv(struct thread_data *td, struct io_u *io_u) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; int ret, flags = 0; @@ -595,13 +612,18 @@ static int fio_netio_recv(struct thread_data *td, struct io_u *io_u) ret = recvfrom(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen, flags, from, len); - if (is_udp_close(io_u, ret)) { + if (is_close_msg(io_u, ret)) { td->done = 1; return 0; } } else { ret = recv(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen, flags); + + if (is_close_msg(io_u, ret)) { + td->done = 1; + return 0; + } } if (ret > 0) break; @@ -615,15 +637,16 @@ static int fio_netio_recv(struct thread_data *td, struct io_u *io_u) } while (1); if (is_udp(o) && td->o.verify == VERIFY_NONE) - verify_udp_seq(nd, io_u); + verify_udp_seq(td, nd, io_u); return ret; } -static int __fio_netio_queue(struct thread_data *td, struct io_u *io_u, - enum fio_ddir ddir) +static enum fio_q_status __fio_netio_queue(struct thread_data *td, + struct io_u *io_u, + enum fio_ddir ddir) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; int ret; @@ -665,7 +688,8 @@ static int __fio_netio_queue(struct thread_data *td, struct io_u *io_u, return FIO_Q_COMPLETED; } -static int fio_netio_queue(struct thread_data *td, struct io_u *io_u) +static enum fio_q_status fio_netio_queue(struct thread_data *td, + struct io_u *io_u) { struct netio_options *o = td->eo; int ret; @@ -689,7 +713,7 @@ static int fio_netio_queue(struct thread_data *td, struct io_u *io_u) static int fio_netio_connect(struct thread_data *td, struct fio_file *f) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; int type, domain; @@ -804,7 +828,7 @@ static int fio_netio_connect(struct thread_data *td, struct fio_file *f) static int fio_netio_accept(struct thread_data *td, struct fio_file *f) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; socklen_t socklen; int state; @@ -854,9 +878,9 @@ err: return 1; } -static void fio_netio_udp_close(struct thread_data *td, struct fio_file *f) +static void fio_netio_send_close(struct thread_data *td, struct fio_file *f) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; struct udp_close_msg msg; struct sockaddr *to; @@ -871,8 +895,8 @@ static void fio_netio_udp_close(struct thread_data *td, struct fio_file *f) len = sizeof(nd->addr); } - msg.magic = htonl(FIO_LINK_OPEN_CLOSE_MAGIC); - msg.cmd = htonl(FIO_LINK_CLOSE); + msg.magic = cpu_to_le32((uint32_t) FIO_LINK_OPEN_CLOSE_MAGIC); + msg.cmd = cpu_to_le32((uint32_t) FIO_LINK_CLOSE); ret = sendto(f->fd, (void *) &msg, sizeof(msg), MSG_WAITALL, to, len); if (ret < 0) @@ -881,21 +905,17 @@ static void fio_netio_udp_close(struct thread_data *td, struct fio_file *f) static int fio_netio_close_file(struct thread_data *td, struct fio_file *f) { - struct netio_options *o = td->eo; - /* - * If this is an UDP connection, notify the receiver that we are - * closing down the link + * Notify the receiver that we are closing down the link */ - if (is_udp(o)) - fio_netio_udp_close(td, f); + fio_netio_send_close(td, f); return generic_close_file(td, f); } static int fio_netio_udp_recv_open(struct thread_data *td, struct fio_file *f) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; struct udp_close_msg msg; struct sockaddr *to; @@ -927,9 +947,9 @@ static int fio_netio_udp_recv_open(struct thread_data *td, struct fio_file *f) return 0; } -static int fio_netio_udp_send_open(struct thread_data *td, struct fio_file *f) +static int fio_netio_send_open(struct thread_data *td, struct fio_file *f) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; struct udp_close_msg msg; struct sockaddr *to; @@ -973,7 +993,7 @@ static int fio_netio_open_file(struct thread_data *td, struct fio_file *f) if (is_udp(o)) { if (td_write(td)) - ret = fio_netio_udp_send_open(td, f); + ret = fio_netio_send_open(td, f); else { int state; @@ -1031,7 +1051,7 @@ static int fio_fill_addr(struct thread_data *td, const char *host, int af, static int fio_netio_setup_connect_inet(struct thread_data *td, const char *host, unsigned short port) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; struct addrinfo *res = NULL; void *dst, *src; @@ -1081,7 +1101,7 @@ static int fio_netio_setup_connect_inet(struct thread_data *td, static int fio_netio_setup_connect_unix(struct thread_data *td, const char *path) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct sockaddr_un *soun = &nd->addr_un; soun->sun_family = AF_UNIX; @@ -1102,7 +1122,7 @@ static int fio_netio_setup_connect(struct thread_data *td) static int fio_netio_setup_listen_unix(struct thread_data *td, const char *path) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct sockaddr_un *addr = &nd->addr_un; mode_t mode; int len, fd; @@ -1135,7 +1155,7 @@ static int fio_netio_setup_listen_unix(struct thread_data *td, const char *path) static int fio_netio_setup_listen_inet(struct thread_data *td, short port) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; struct ip_mreq mr; struct sockaddr_in sin; @@ -1198,7 +1218,7 @@ static int fio_netio_setup_listen_inet(struct thread_data *td, short port) return 1; } if (is_ipv6(o)) { - log_err("fio: IPv6 not supported for multicast network IO"); + log_err("fio: IPv6 not supported for multicast network IO\n"); close(fd); return 1; } @@ -1251,7 +1271,7 @@ static int fio_netio_setup_listen_inet(struct thread_data *td, short port) static int fio_netio_setup_listen(struct thread_data *td) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; struct netio_options *o = td->eo; int ret; @@ -1297,6 +1317,8 @@ static int fio_netio_init(struct thread_data *td) return 1; } + o->port += td->subjob_number; + if (!is_tcp(o)) { if (o->listen) { log_err("fio: listen only valid for TCP proto IO\n"); @@ -1324,7 +1346,7 @@ static int fio_netio_init(struct thread_data *td) static void fio_netio_cleanup(struct thread_data *td) { - struct netio_data *nd = td->io_ops->data; + struct netio_data *nd = td->io_ops_data; if (nd) { if (nd->listenfd != -1) @@ -1348,13 +1370,13 @@ static int fio_netio_setup(struct thread_data *td) td->o.open_files++; } - if (!td->io_ops->data) { - nd = malloc(sizeof(*nd));; + if (!td->io_ops_data) { + nd = malloc(sizeof(*nd)); memset(nd, 0, sizeof(*nd)); nd->listenfd = -1; nd->pipes[0] = nd->pipes[1] = -1; - td->io_ops->data = nd; + td->io_ops_data = nd; } return 0; @@ -1372,7 +1394,7 @@ static int fio_netio_setup_splice(struct thread_data *td) fio_netio_setup(td); - nd = td->io_ops->data; + nd = td->io_ops_data; if (nd) { if (pipe(nd->pipes) < 0) return 1;