diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 193cd03..b5fa863 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -9,9 +9,10 @@ correct test durations for all protocols (#560, #238). * Application-level bandwidth pacing (--bandwidth option) is now - checked every millisecond, instead of of every tenth of a second, - to provide smoother traffic behavior when using application - pacing. (#460) + checked every millisecond by default, instead of of every tenth of + a second, to provide smoother traffic behavior when using + application pacing. (#460) The pacing can be tuned via the use of + the --pacing-timer option. * A new --dscp option allows specifying the DSCP value to be used for outgoing packets (#508). The TOS byte value is now printed in diff --git a/src/iperf.h b/src/iperf.h index c565f42..f6d6cd3 100755 --- a/src/iperf.h +++ b/src/iperf.h @@ -116,6 +116,7 @@ struct iperf_settings int blksize; /* size of read/writes (-l) */ uint64_t rate; /* target data rate for application pacing*/ uint64_t fqrate; /* target data rate for FQ pacing*/ + int pacing_timer; /* pacing timer in microseconds */ int burst; /* packets per burst */ int mss; /* for TCP MSS */ int ttl; /* IP TTL option */ diff --git a/src/iperf3.1 b/src/iperf3.1 index a95aad6..e81db85 100644 --- a/src/iperf3.1 +++ b/src/iperf3.1 @@ -124,6 +124,16 @@ This bandwidth limit is implemented internally inside iperf3, and is available on all platforms. Compare with the \--fq-rate flag. .TP +.BR --pacing-timer " \fIn\fR[KMG]" +set pacing timer interval in microseconds (default 1000 microseconds, +or 1 ms). +This controls iperf3's internal pacing timer for the -b/--bandwidth +option. +The timer fires at the interval set by this parameter. +Smaller values of the pacing timer parameter smooth out the traffic +emitted by iperf3, but potentially at the cost of performance due to +more frequent timer processing. +.TP .BR --fq-rate " \fIn\fR[KM]" Set a rate to be used with fair-queueing based socket-level pacing, in bits per second. diff --git a/src/iperf_api.c b/src/iperf_api.c index 99d8dd7..99c8949 100755 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -681,6 +681,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"authorized-users-path", required_argument, NULL, OPT_SERVER_AUTHORIZED_USERS}, #endif /* HAVE_SSL */ {"fq-rate", required_argument, NULL, OPT_FQ_RATE}, + {"pacing-timer", required_argument, NULL, OPT_PACING_TIMER}, {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} @@ -1012,7 +1013,11 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) test->server_authorized_users = strdup(optarg); break; #endif /* HAVE_SSL */ - case 'h': + case OPT_PACING_TIMER: + test->settings->pacing_timer = unit_atoi(optarg); + client_flag = 1; + break; + case 'h': usage_long(stdout); exit(0); default: @@ -1298,7 +1303,7 @@ iperf_create_send_timers(struct iperf_test * test) if (test->settings->rate != 0) { cd.p = sp; /* (Repeat every millisecond - arbitrary value to provide smooth pacing.) */ - sp->send_timer = tmr_create((struct timeval*) 0, send_timer_proc, cd, 1000L, 1); + sp->send_timer = tmr_create((struct timeval*) 0, send_timer_proc, cd, test->settings->pacing_timer, 1); if (sp->send_timer == NULL) { i_errno = IEINITTEST; return -1; @@ -1460,6 +1465,8 @@ send_parameters(struct iperf_test *test) cJSON_AddNumberToObject(j, "bandwidth", test->settings->rate); if (test->settings->fqrate) cJSON_AddNumberToObject(j, "fqrate", test->settings->fqrate); + if (test->settings->pacing_timer) + cJSON_AddNumberToObject(j, "pacing_timer", test->settings->pacing_timer); if (test->settings->burst) cJSON_AddNumberToObject(j, "burst", test->settings->burst); if (test->settings->tos) @@ -1545,6 +1552,8 @@ get_parameters(struct iperf_test *test) test->settings->rate = j_p->valueint; if ((j_p = cJSON_GetObjectItem(j, "fqrate")) != NULL) test->settings->fqrate = j_p->valueint; + if ((j_p = cJSON_GetObjectItem(j, "pacing_timer")) != NULL) + test->settings->pacing_timer = j_p->valueint; if ((j_p = cJSON_GetObjectItem(j, "burst")) != NULL) test->settings->burst = j_p->valueint; if ((j_p = cJSON_GetObjectItem(j, "TOS")) != NULL) @@ -2037,6 +2046,7 @@ iperf_defaults(struct iperf_test *testp) testp->settings->blksize = DEFAULT_TCP_BLKSIZE; testp->settings->rate = 0; testp->settings->fqrate = 0; + testp->settings->pacing_timer = 1000; testp->settings->burst = 0; testp->settings->mss = 0; testp->settings->bytes = 0; diff --git a/src/iperf_api.h b/src/iperf_api.h index 061200d..d8df677 100755 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -58,6 +58,7 @@ struct iperf_stream; #define OPT_CLIENT_RSA_PUBLIC_KEY 13 #define OPT_SERVER_RSA_PRIVATE_KEY 14 #define OPT_SERVER_AUTHORIZED_USERS 15 +#define OPT_PACING_TIMER 16 /* states */ #define TEST_START 1 diff --git a/src/iperf_locale.c b/src/iperf_locale.c index d72005a..07f6000 100644 --- a/src/iperf_locale.c +++ b/src/iperf_locale.c @@ -134,6 +134,7 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" " -b, --bandwidth #[KMG][/#] target bandwidth in bits/sec (0 for unlimited)\n" " (default %d Mbit/sec for UDP, unlimited for TCP)\n" " (optional slash and packet count for burst mode)\n" + " --pacing-timer #[KMG] set the timing for pacing, in microseconds (default 1000)\n" #if defined(HAVE_SO_MAX_PACING_RATE) " --fq-rate #[KMG] enable fair-queuing based socket pacing in\n" " bits/sec (Linux only)\n"