From: Jens Axboe Date: Thu, 9 Oct 2014 17:55:16 +0000 (-0600) Subject: engines/net: add socket buffer window size setting X-Git-Tag: fio-2.1.14~80 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=1008602c5af0b098b45020a0ac63408d979a41b0;p=fio.git engines/net: add socket buffer window size setting Signed-off-by: Jens Axboe --- diff --git a/HOWTO b/HOWTO index 2cecbbba..f78e47c1 100644 --- a/HOWTO +++ b/HOWTO @@ -1672,6 +1672,7 @@ that defines them is selected. [net] listen For TCP network connections, tell fio to listen for incoming connections rather than initiating an outgoing connection. The hostname must be omitted if this option is used. + [net] pingpong Normaly a network writer will just continue writing data, and a network reader will just consume packages. If pingpong=1 is set, a writer will send its normal payload to the reader, @@ -1684,6 +1685,8 @@ that defines them is selected. single reader when multiple readers are listening to the same address. +[net] window_size Set the desired socket buffer size for the connection. + [e4defrag] donorname=str File will be used as a block donor(swap extents between files) [e4defrag] inplace=int diff --git a/configure b/configure index e3ec2523..3e3c9785 100755 --- a/configure +++ b/configure @@ -1074,6 +1074,25 @@ if compile_prog "" "" "TCP_NODELAY"; then fi echo "TCP_NODELAY $tcp_nodelay" +########################################## +# Check whether we have SO_SNDBUF +window_size="no" +cat > $TMPC << EOF +#include +#include +#include +#include +int main(int argc, char **argv) +{ + setsockopt(0, SOL_SOCKET, SO_SNDBUF, NULL, 0); + setsockopt(0, SOL_SOCKET, SO_RCVBUF, NULL, 0); +} +EOF +if compile_prog "" "" "SO_SNDBUF"; then + window_size="yes" +fi +echo "Net engine window_size $window_size" + ########################################## # Check whether we have RLIMIT_MEMLOCK rlimit_memlock="no" @@ -1429,6 +1448,9 @@ fi if test "$tcp_nodelay" = "yes" ; then output_sym "CONFIG_TCP_NODELAY" fi +if test "$window_size" = "yes" ; then + output_sym "CONFIG_NET_WINDOWSIZE" +fi if test "$rlimit_memlock" = "yes" ; then output_sym "CONFIG_RLIMIT_MEMLOCK" fi diff --git a/engines/net.c b/engines/net.c index 61bdfdd1..ac5a93c8 100644 --- a/engines/net.c +++ b/engines/net.c @@ -39,6 +39,7 @@ struct netio_options { unsigned int pingpong; unsigned int nodelay; unsigned int ttl; + unsigned int window_size; char *intfc; }; @@ -165,6 +166,18 @@ static struct fio_option options[] = { .category = FIO_OPT_C_ENGINE, .group = FIO_OPT_G_NETIO, }, +#ifdef CONFIG_NET_WINDOWSIZE + { + .name = "window_size", + .lname = "Window Size", + .type = FIO_OPT_INT, + .off1 = offsetof(struct netio_options, window_size), + .minval = 0, + .help = "Set socket buffer window size", + .category = FIO_OPT_C_ENGINE, + .group = FIO_OPT_G_NETIO, + }, +#endif { .name = NULL, }, @@ -185,6 +198,41 @@ static inline int is_ipv6(struct netio_options *o) return o->proto == FIO_TYPE_UDP_V6 || o->proto == FIO_TYPE_TCP_V6; } +static int set_window_size(struct thread_data *td, int fd) +{ +#ifdef CONFIG_NET_WINDOWSIZE + struct netio_options *o = td->eo; + unsigned int wss; + int snd, rcv, ret; + + if (!o->window_size) + return 0; + + rcv = o->listen || o->pingpong; + snd = !o->listen || o->pingpong; + wss = o->window_size; + ret = 0; + + if (rcv) { + ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *) &wss, + sizeof(wss)); + if (ret < 0) + td_verror(td, errno, "rcvbuf window size"); + } + if (snd && !ret) { + ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *) &wss, + sizeof(wss)); + if (ret < 0) + td_verror(td, errno, "sndbuf window size"); + } + + return ret; +#else + td_verror(td, -EINVAL, "setsockopt window size"); + return -1; +#endif +} + /* * Return -1 for error and 'nr events' for a positive number * of events @@ -603,6 +651,11 @@ static int fio_netio_connect(struct thread_data *td, struct fio_file *f) } #endif + if (set_window_size(td, f->fd)) { + close(f->fd); + return 1; + } + if (is_udp(o)) { if (!fio_netio_is_multicast(td->o.filename)) return 0; @@ -1044,6 +1097,11 @@ static int fio_netio_setup_listen_inet(struct thread_data *td, short port) } #endif + if (set_window_size(td, fd)) { + close(fd); + return 1; + } + if (td->o.filename) { if (!is_udp(o) || !fio_netio_is_multicast(td->o.filename)) { log_err("fio: hostname not valid for non-multicast inbound network IO\n"); diff --git a/fio.1 b/fio.1 index 91c30748..dc727d36 100644 --- a/fio.1 +++ b/fio.1 @@ -1525,6 +1525,9 @@ completion latency measures how long it took for the other end to receive and send back. For UDP multicast traffic pingpong=1 should only be set for a single reader when multiple readers are listening to the same address. .TP +.BI (net, window_size) \fR=\fPint +Set the desired socket buffer size for the connection. +.TP .BI (e4defrag,donorname) \fR=\fPstr File will be used as a block donor (swap extents between files) .TP