From 9915746a8bf88050cd4cfee4295d063c1154e9a0 Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Thu, 26 May 2016 09:47:48 -0700 Subject: [PATCH] Squashed commit of the following: commit 2dc03630a736be2ae9f64823aabb5776e7074c2a Merge: 61e325c 0da552c Author: Bruce A. Mah Date: Thu May 26 09:40:58 2016 -0700 Merge branch 'master' into issue-325 commit 61e325c5d0a4e7a9823221ce507db0f478fc98b5 Merge: 227992f ccbcee6 Author: Bruce A. Mah Date: Thu May 26 11:09:54 2016 -0400 Merge branch 'issue-325' of github.com:esnet/iperf into issue-325 Conflicts: src/iperf3.1 commit 227992f366e7f4895b6762011576ba22a42a752e Author: Bruce A. Mah Date: Thu May 26 11:07:01 2016 -0400 Don't set SO_MAX_PACING_RATE if the rate is 0. Also tweak some help text. Towards #325, in response to feedback from @bltierney. commit ccbcee6366d50ec632fc00eb11fde8a886f8febe Author: Bruce A. Mah Date: Tue May 24 09:19:41 2016 -0700 Fix manpage formatting for consistency. commit 90ac5a9ce09bd746ca5f943a8226ab864da3ebf8 Author: Bruce A. Mah Date: Tue May 24 12:14:16 2016 -0400 Add some documentation for fair-queueing per-socket pacing. For #325. commit 5571059870f7aefefb574816de70b6406848888f Author: Bruce A. Mah Date: Tue May 24 11:55:44 2016 -0400 Change the fair-queueing socket pacing logic in response to feedback. By default, on platforms where per-socket pacing is available, it will be used. If not available, iperf3 will fall back to application- level pacing. The --no-fq-socket-pacing option can be used to forcibly disable fair-queueing per-socket pacing. (The earlier --socket-pacing option has been removed.) Tested on CentOS 7, more testing on other platforms is required to be sure it didn't break the old application-level pacing behavior. For #325. commit 3e3f506fe9f375a5771c9e3ddfe8677c1a7146e7 Merge: 50a379e 3b23112 Author: Bruce A. Mah Date: Tue May 24 09:54:39 2016 -0400 Merge branch 'master' into issue-325 commit 50a379eddfa89d1313d2aeeb62a6fbc82f00ea17 Author: Bruce A. Mah Date: Sat Apr 16 02:55:42 2016 -0400 Regen. commit 200d3fe3917b3d298bdf52a0bde32c47cf2727b0 Author: Bruce A. Mah Date: Sat Apr 16 02:41:32 2016 -0400 Checkpoint for initial work on #325 to add socket pacing. This works only on Linux and depends on the availability of the SO_MAX_PACING_RATE socket option and the fq queue discipline. Use --socket-pacing to use SO_MAX_PACING_RATE instead of the default iperf3 user-level rate limiting; in either case, the --bandwidth parameter controls the desired rate. Lightly tested with both --tcp and --udp, normal and --reverse. Real testing requires analysis of packet timestamps between multiple hosts. --- Makefile.in | 53 ++++++++++++++----------------------------- configure.ac | 16 ++++++++++++- examples/Makefile.in | 30 ++++++++---------------- src/Makefile.in | 42 ++++++++++++---------------------- src/iperf.h | 4 ++-- src/iperf3.1 | 8 +++++++ src/iperf_api.c | 31 +++++++++++++++++++++++-- src/iperf_api.h | 4 +++- src/iperf_config.h.in | 6 ++++- src/iperf_error.c | 6 ++++- src/iperf_locale.c | 6 ++++- src/iperf_tcp.c | 35 +++++++++++++++++++++++++++- src/iperf_udp.c | 36 ++++++++++++++++++++++++++++- src/iperf_util.c | 12 +++++++++- 14 files changed, 192 insertions(+), 97 deletions(-) diff --git a/Makefile.in b/Makefile.in index c8020fd..6d5d571 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,17 +14,7 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -88,12 +78,20 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(top_srcdir)/config/mkinstalldirs $(srcdir)/iperf3.spec.in \ + INSTALL config/compile config/config.guess config/config.sub \ + config/depcomp config/install-sh config/missing \ + config/mkinstalldirs config/ltmain.sh \ + $(top_srcdir)/config/config.guess \ + $(top_srcdir)/config/config.sub \ + $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \ + $(top_srcdir)/config/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs @@ -156,14 +154,6 @@ ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/iperf3.spec.in \ - $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \ - $(top_srcdir)/config/config.sub \ - $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \ - $(top_srcdir)/config/missing \ - $(top_srcdir)/config/mkinstalldirs INSTALL config/compile \ - config/config.guess config/config.sub config/install-sh \ - config/ltmain.sh config/missing config/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -245,7 +235,6 @@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -341,6 +330,7 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -558,16 +548,10 @@ dist-xz: distdir $(am__post_remove_distdir) dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) @@ -602,17 +586,16 @@ distcheck: dist esac chmod -R a-w $(distdir) chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -788,8 +771,6 @@ uninstall-am: mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am -.PRECIOUS: Makefile - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/configure.ac b/configure.ac index e59a967..d3eb8f7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# iperf, Copyright (c) 2014, 2015, The Regents of the University of +# iperf, Copyright (c) 2014, 2015, 2016, The Regents of the University of # California, through Lawrence Berkeley National Laboratory (subject # to receipt of any required approvals from the U.S. Dept. of # Energy). All rights reserved. @@ -141,4 +141,18 @@ AC_CHECK_FUNCS([cpuset_setaffinity sched_setaffinity], # it needs and what arguments it expects. AC_CHECK_FUNCS([sendfile]) +# Check for packet pacing socket option (Linux only for now). +AC_CACHE_CHECK([SO_MAX_PACING_RATE socket option], +[iperf3_cv_header_so_max_pacing_rate], +AC_EGREP_CPP(yes, +[#include +#ifdef SO_MAX_PACING_RATE + yes +#endif +],iperf3_cv_header_so_max_pacing_rate=yes,iperf3_cv_header_so_max_pacing_rate=no)) +if test "x$iperf3_cv_header_so_max_pacing_rate" = "xyes"; then + AC_DEFINE([HAVE_SO_MAX_PACING_RATE], [1], [Have SO_MAX_PACING_RATE sockopt.]) +fi + + AC_OUTPUT([Makefile src/Makefile src/version.h examples/Makefile iperf3.spec]) diff --git a/examples/Makefile.in b/examples/Makefile.in index 0c0018f..e18f031 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,17 +15,7 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -90,11 +80,13 @@ build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = mic$(EXEEXT) mis$(EXEEXT) subdir = examples +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/config/mkinstalldirs \ + $(top_srcdir)/config/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/src/iperf_config.h CONFIG_CLEAN_FILES = @@ -176,8 +168,6 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ - $(top_srcdir)/config/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -218,7 +208,6 @@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -320,6 +309,7 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -369,14 +359,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -622,8 +612,6 @@ uninstall-am: mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am -.PRECIOUS: Makefile - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/Makefile.in b/src/Makefile.in index f7c46ad..e044f88 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -17,17 +17,7 @@ VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -95,12 +85,15 @@ noinst_PROGRAMS = t_timer$(EXEEXT) t_units$(EXEEXT) t_uuid$(EXEEXT) \ iperf3_profile$(EXEEXT) TESTS = t_timer$(EXEEXT) t_units$(EXEEXT) t_uuid$(EXEEXT) subdir = src +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/iperf_config.h.in $(top_srcdir)/config/mkinstalldirs \ + $(srcdir)/version.h.in $(top_srcdir)/config/depcomp \ + $(dist_man_MANS) $(include_HEADERS) \ + $(top_srcdir)/config/test-driver ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ - $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = iperf_config.h CONFIG_CLEAN_FILES = version.h @@ -439,11 +432,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) -am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ - $(srcdir)/iperf_config.h.in $(srcdir)/version.h.in \ - $(top_srcdir)/config/depcomp \ - $(top_srcdir)/config/mkinstalldirs \ - $(top_srcdir)/config/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -484,7 +472,6 @@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -645,6 +632,7 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -664,8 +652,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): iperf_config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/iperf_config.h.in $(top_builddir)/config.status @rm -f stamp-h1 @@ -843,14 +831,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -1334,7 +1322,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ - elif test -n "$$redo_logs"; then \ + else \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ @@ -1651,8 +1639,6 @@ uninstall-man: uninstall-man1 uninstall-man3 uninstall-libLTLIBRARIES uninstall-man uninstall-man1 \ uninstall-man3 -.PRECIOUS: Makefile - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/iperf.h b/src/iperf.h index 7182cf5..5e56e48 100755 --- a/src/iperf.h +++ b/src/iperf.h @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014, 2015, The Regents of the University of + * iperf, Copyright (c) 2014, 2015, 2016, The Regents of the University of * California, through Lawrence Berkeley National Laboratory (subject * to receipt of any required approvals from the U.S. Dept. of * Energy). All rights reserved. @@ -241,7 +241,7 @@ struct iperf_test int get_server_output; /* --get-server-output */ int udp_counters_64bit; /* --use-64-bit-udp-counters */ int forceflush; /* --forceflush - flushing output at every interval */ - + int no_fq_socket_pacing; /* --no-fq-socket-pacing */ int multisend; char *json_output_string; /* rendered JSON output if json_output is set */ diff --git a/src/iperf3.1 b/src/iperf3.1 index 5bc3736..8063cba 100644 --- a/src/iperf3.1 +++ b/src/iperf3.1 @@ -107,6 +107,14 @@ It will send the given number of packets without pausing, even if that temporarily exceeds the specified bandwidth limit. Setting the target bandwidth to 0 will disable bandwidth limits (particularly useful for UDP tests). +On platforms supporting the \fCSO_MAX_PACING_RATE\fR socket option +(currently only Linux), fair-queueing socket-level pacing, implemented in +the kernel, will be used. +On other platforms, iperf3 will implement its own rate control. +.TP +.BR --no-fq-socket-pacing +disable the use of fair-queueing based socket-level pacing with the -b +option, and rely on iperf3's internal rate control. .TP .BR -t ", " --time " \fIn\fR" time in seconds to transmit for (default 10 secs) diff --git a/src/iperf_api.c b/src/iperf_api.c index 25ded84..2d9c4ce 100755 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -270,6 +270,12 @@ iperf_get_test_one_off(struct iperf_test *ipt) return ipt->one_off; } +int +iperf_get_no_fq_socket_pacing(struct iperf_test *ipt) +{ + return ipt->no_fq_socket_pacing; +} + /************** Setter routines for some fields inside iperf_test *************/ void @@ -441,6 +447,12 @@ iperf_set_test_one_off(struct iperf_test *ipt, int one_off) ipt->one_off = one_off; } +void +iperf_set_no_fq_socket_pacing(struct iperf_test *ipt, int no_pacing) +{ + ipt->no_fq_socket_pacing = no_pacing; +} + /********************** Get/set test protocol structure ***********************/ struct protocol * @@ -656,6 +668,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"forceflush", no_argument, NULL, OPT_FORCEFLUSH}, {"get-server-output", no_argument, NULL, OPT_GET_SERVER_OUTPUT}, {"udp-counters-64bit", no_argument, NULL, OPT_UDP_COUNTERS_64BIT}, + {"no-fq-socket-pacing", no_argument, NULL, OPT_NO_FQ_SOCKET_PACING}, {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} @@ -938,6 +951,14 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) case OPT_UDP_COUNTERS_64BIT: test->udp_counters_64bit = 1; break; + case OPT_NO_FQ_SOCKET_PACING: +#if defined(HAVE_SO_MAX_PACING_RATE) + test->no_fq_socket_pacing = 1; +#else /* HAVE_SO_MAX_PACING_RATE */ + i_errno = IEUNIMP; + return -1; +#endif + break; case 'h': default: usage_long(); @@ -1069,8 +1090,9 @@ iperf_send(struct iperf_test *test, fd_set *write_setP) gettimeofday(&now, NULL); streams_active = 0; SLIST_FOREACH(sp, &test->streams, streams) { - if (sp->green_light && - (write_setP == NULL || FD_ISSET(sp->socket, write_setP))) { + if (! test->no_fq_socket_pacing || + (sp->green_light && + (write_setP == NULL || FD_ISSET(sp->socket, write_setP)))) { if ((r = sp->snd(sp)) < 0) { if (r == NET_SOFTERROR) break; @@ -1316,6 +1338,8 @@ send_parameters(struct iperf_test *test) cJSON_AddIntToObject(j, "get_server_output", iperf_get_test_get_server_output(test)); if (test->udp_counters_64bit) cJSON_AddIntToObject(j, "udp_counters_64bit", iperf_get_test_udp_counters_64bit(test)); + if (test->no_fq_socket_pacing) + cJSON_AddIntToObject(j, "no_fq_socket_pacing", iperf_get_no_fq_socket_pacing(test)); cJSON_AddStringToObject(j, "client_version", IPERF_VERSION); @@ -1394,6 +1418,9 @@ get_parameters(struct iperf_test *test) iperf_set_test_get_server_output(test, 1); if ((j_p = cJSON_GetObjectItem(j, "udp_counters_64bit")) != NULL) iperf_set_test_udp_counters_64bit(test, 1); + if ((j_p = cJSON_GetObjectItem(j, "no_fq_socket_pacing")) != NULL) + iperf_set_no_fq_socket_pacing(test, 1); + if (test->sender && test->protocol->id == Ptcp && has_tcpinfo_retransmits()) test->sender_has_retransmits = 1; cJSON_Delete(j); diff --git a/src/iperf_api.h b/src/iperf_api.h index 5a7d40a..9a8d19f 100755 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014, 2015, The Regents of the University of + * iperf, Copyright (c) 2014, 2015, 2016, The Regents of the University of * California, through Lawrence Berkeley National Laboratory (subject * to receipt of any required approvals from the U.S. Dept. of * Energy). All rights reserved. @@ -51,6 +51,7 @@ struct iperf_stream; #define OPT_CLIENT_PORT 5 #define OPT_NUMSTREAMS 6 #define OPT_FORCEFLUSH 7 +#define OPT_NO_FQ_SOCKET_PACING 9 /* states */ #define TEST_START 1 @@ -332,6 +333,7 @@ enum { IESETSCTPDISABLEFRAG = 137, // Unable to set SCTP Fragmentation (check perror) IESETSCTPNSTREAM= 138, // Unable to set SCTP number of streams (check perror) IESETSCTPBINDX= 139, // Unable to process sctp_bindx() parameters + IESETPACING= 140, // Unable to set socket pacing rate /* Stream errors */ IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror) IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror) diff --git a/src/iperf_config.h.in b/src/iperf_config.h.in index 69dbb7a..c949e22 100644 --- a/src/iperf_config.h.in +++ b/src/iperf_config.h.in @@ -30,6 +30,9 @@ /* Define to 1 if you have the `sendfile' function. */ #undef HAVE_SENDFILE +/* Have SO_MAX_PACING_RATE sockopt. */ +#undef HAVE_SO_MAX_PACING_RATE + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H @@ -60,7 +63,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H -/* Define to the sub-directory where libtool stores uninstalled libraries. */ +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ #undef LT_OBJDIR /* Name of package */ diff --git a/src/iperf_error.c b/src/iperf_error.c index 9a752d3..a64c212 100644 --- a/src/iperf_error.c +++ b/src/iperf_error.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014, 2015, The Regents of the University of + * iperf, Copyright (c) 2014, 2015, 2016, The Regents of the University of * California, through Lawrence Berkeley National Laboratory (subject * to receipt of any required approvals from the U.S. Dept. of * Energy). All rights reserved. @@ -355,6 +355,10 @@ iperf_strerror(int i_errno) snprintf(errstr, len, "unable to set SCTP_INIT num of SCTP streams\n"); perr = 1; break; + case IESETPACING: + snprintf(errstr, len, "unable to set socket pacing"); + perr = 1; + break; } if (herr || perr) diff --git a/src/iperf_locale.c b/src/iperf_locale.c index 4404059..bfb5505 100644 --- a/src/iperf_locale.c +++ b/src/iperf_locale.c @@ -1,5 +1,5 @@ /*--------------------------------------------------------------- - * iperf, Copyright (c) 2014, The Regents of the University of + * iperf, Copyright (c) 2014, 2016, The Regents of the University of * California, through Lawrence Berkeley National Laboratory (subject * to receipt of any required approvals from the U.S. Dept. of * Energy). All rights reserved. @@ -153,6 +153,10 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n" " -T, --title str prefix every output line with this string\n" " --get-server-output get results from server\n" " --udp-counters-64bit use 64-bit counters in UDP test packets\n" +#if defined(HAVE_SO_MAX_PACING_RATE) + " --no-fq-socket-pacing disable fair-queuing based socket pacing\n" + " (Linux only)\n" +#endif #ifdef NOT_YET_SUPPORTED /* still working on these */ #endif diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c index 78501fe..ac3b392 100644 --- a/src/iperf_tcp.c +++ b/src/iperf_tcp.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014, The Regents of the University of + * iperf, Copyright (c) 2014, 2016, The Regents of the University of * California, through Lawrence Berkeley National Laboratory (subject * to receipt of any required approvals from the U.S. Dept. of * Energy). All rights reserved. @@ -245,6 +245,22 @@ iperf_tcp_listen(struct iperf_test *test) } } #endif /* HAVE_TCP_CONGESTION */ +#if defined(HAVE_SO_MAX_PACING_RATE) + /* If socket pacing is available and not disabled, try it. */ + if (! test->no_fq_socket_pacing) { + /* Convert bits per second to bytes per second */ + unsigned int rate = test->settings->rate / 8; + if (rate > 0) { + if (test->debug) { + printf("Setting fair-queue socket pacing to %u\n", rate); + } + if (setsockopt(s, SOL_SOCKET, SO_MAX_PACING_RATE, &rate, sizeof(rate)) < 0) { + warning("Unable to set socket pacing, using application pacing instead"); + test->no_fq_socket_pacing = 1; + } + } + } +#endif /* HAVE_SO_MAX_PACING_RATE */ opt = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { saved_errno = errno; @@ -468,6 +484,23 @@ iperf_tcp_connect(struct iperf_test *test) } #endif /* HAVE_TCP_CONGESTION */ +#if defined(HAVE_SO_MAX_PACING_RATE) + /* If socket pacing is available and not disabled, try it. */ + if (! test->no_fq_socket_pacing) { + /* Convert bits per second to bytes per second */ + unsigned int rate = test->settings->rate / 8; + if (rate > 0) { + if (test->debug) { + printf("Socket pacing set to %u\n", rate); + } + if (setsockopt(s, SOL_SOCKET, SO_MAX_PACING_RATE, &rate, sizeof(rate)) < 0) { + warning("Unable to set socket pacing, using application pacing instead"); + test->no_fq_socket_pacing = 1; + } + } + } +#endif /* HAVE_SO_MAX_PACING_RATE */ + if (connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen) < 0 && errno != EINPROGRESS) { saved_errno = errno; close(s); diff --git a/src/iperf_udp.c b/src/iperf_udp.c index 9500aa1..fd426e1 100644 --- a/src/iperf_udp.c +++ b/src/iperf_udp.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014, The Regents of the University of + * iperf, Copyright (c) 2014, 2016, The Regents of the University of * California, through Lawrence Berkeley National Laboratory (subject * to receipt of any required approvals from the U.S. Dept. of * Energy). All rights reserved. @@ -244,6 +244,23 @@ iperf_udp_accept(struct iperf_test *test) } } +#if defined(HAVE_SO_MAX_PACING_RATE) + /* If socket pacing is available and not disabled, try it. */ + if (! test->no_fq_socket_pacing) { + /* Convert bits per second to bytes per second */ + unsigned int rate = test->settings->rate / 8; + if (rate > 0) { + if (test->debug) { + printf("Setting fair-queue socket pacing to %u\n", rate); + } + if (setsockopt(s, SOL_SOCKET, SO_MAX_PACING_RATE, &rate, sizeof(rate)) < 0) { + warning("Unable to set socket pacing, using application pacing instead"); + test->no_fq_socket_pacing = 1; + } + } + } +#endif /* HAVE_SO_MAX_PACING_RATE */ + /* * Create a new "listening" socket to replace the one we were using before. */ @@ -326,6 +343,23 @@ iperf_udp_connect(struct iperf_test *test) } } +#if defined(HAVE_SO_MAX_PACING_RATE) + /* If socket pacing is available and not disabled, try it. */ + if (! test->no_fq_socket_pacing) { + /* Convert bits per second to bytes per second */ + unsigned int rate = test->settings->rate / 8; + if (rate > 0) { + if (test->debug) { + printf("Setting fair-queue socket pacing to %u\n", rate); + } + if (setsockopt(s, SOL_SOCKET, SO_MAX_PACING_RATE, &rate, sizeof(rate)) < 0) { + warning("Unable to set socket pacing, using application pacing instead"); + test->no_fq_socket_pacing = 1; + } + } + } +#endif /* HAVE_SO_MAX_PACING_RATE */ + #ifdef SO_RCVTIMEO /* 30 sec timeout for a case when there is a network problem. */ tv.tv_sec = 30; diff --git a/src/iperf_util.c b/src/iperf_util.c index 7142ee1..5421ccc 100644 --- a/src/iperf_util.c +++ b/src/iperf_util.c @@ -1,5 +1,5 @@ /* - * iperf, Copyright (c) 2014, The Regents of the University of + * iperf, Copyright (c) 2014, 2016, The Regents of the University of * California, through Lawrence Berkeley National Laboratory (subject * to receipt of any required approvals from the U.S. Dept. of * Energy). All rights reserved. @@ -285,6 +285,16 @@ get_optional_features(void) numfeatures++; #endif /* HAVE_SENDFILE */ +#if defined(HAVE_SO_MAX_PACING_RATE) + if (numfeatures > 0) { + strncat(features, ", ", + sizeof(features) - strlen(features) - 1); + } + strncat(features, "socket pacing", + sizeof(features) - strlen(features) - 1); + numfeatures++; +#endif /* HAVE_SO_MAX_PACING_RATE */ + if (numfeatures == 0) { strncat(features, "None", sizeof(features) - strlen(features) - 1);