From db37d89074ed204c9c2bd010e72f63dcf4725715 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 14 Dec 2017 11:51:41 -0700 Subject: [PATCH] Allow configurable ETA intervals By default, fio prints ETA output every second. For some client/server setups, it's desirable to allow a much longer interval, to avoid spending too much time getting and printing ETA time. Takes a normal time input, allowing usec/msec/sec etc postfixes. Signed-off-by: Jens Axboe --- HOWTO | 11 ++++++++++- client.c | 2 +- eta.c | 13 +++++++++---- fio.1 | 9 ++++++++- fio.h | 3 +++ init.c | 29 +++++++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/HOWTO b/HOWTO index 563ca933..78fa6ccf 100644 --- a/HOWTO +++ b/HOWTO @@ -173,7 +173,16 @@ Command line options .. option:: --eta=when Specifies when real-time ETA estimate should be printed. `when` may be - `always`, `never` or `auto`. + `always`, `never` or `auto`. `auto` is the default, it prints ETA + when requested if the output is a TTY. `always` disregards the output + type, and prints ETA when requested. `never` never prints ETA. + +.. option:: --eta-interval=time + + By default, fio requests client ETA status roughly every second. With + this option, the interval is configurable. Fio imposes a minimum + allowed time to avoid flooding the console, less than 250 msec is + not supported. .. option:: --eta-newline=time diff --git a/client.c b/client.c index 82e12855..18247ef6 100644 --- a/client.c +++ b/client.c @@ -2000,7 +2000,7 @@ int fio_handle_clients(struct client_ops *ops) int timeout; fio_gettime(&ts, NULL); - if (mtime_since(&eta_ts, &ts) >= 900) { + if (eta_time_within_slack(mtime_since(&eta_ts, &ts))) { request_client_etas(ops); memcpy(&eta_ts, &ts, sizeof(ts)); diff --git a/eta.c b/eta.c index 1b0b000d..8b77dafa 100644 --- a/eta.c +++ b/eta.c @@ -347,6 +347,14 @@ static void calc_iops(int unified_rw_rep, unsigned long mtime, } } +/* + * Allow a little slack - if we're within 95% of the time, allow ETA. + */ +bool eta_time_within_slack(unsigned int time) +{ + return time > ((eta_interval_msec * 95) / 100); +} + /* * Print status of the jobs we know about. This includes rate estimates, * ETA, thread state, etc. @@ -489,10 +497,7 @@ bool calc_thread_status(struct jobs_eta *je, int force) disp_time = mtime_since(&disp_prev_time, &now); - /* - * Allow a little slack, the target is to print it every 1000 msecs - */ - if (!force && disp_time < 900) + if (!force && !eta_time_within_slack(disp_time)) return false; calc_rate(unified_rw_rep, disp_time, io_bytes, disp_io_bytes, je->rate); diff --git a/fio.1 b/fio.1 index 57ab6656..70eeeb0f 100644 --- a/fio.1 +++ b/fio.1 @@ -77,7 +77,14 @@ the I/O engine core to prevent writes due to unknown user space bug(s). .TP .BI \-\-eta \fR=\fPwhen Specifies when real\-time ETA estimate should be printed. \fIwhen\fR may -be `always', `never' or `auto'. +be `always', `never' or `auto'. `auto' is the default, it prints ETA when +requested if the output is a TTY. `always' disregards the output type, and +prints ETA when requested. `never' never prints ETA. +.TP +.BI \-\-eta\-interval \fR=\fPtime +By default, fio requests client ETA status roughly every second. With this +option, the interval is configurable. Fio imposes a minimum allowed time to +avoid flooding the console, less than 250 msec is not supported. .TP .BI \-\-eta\-newline \fR=\fPtime Force a new line for every \fItime\fR period passed. When the unit is omitted, diff --git a/fio.h b/fio.h index 8a656461..b3b95efb 100644 --- a/fio.h +++ b/fio.h @@ -505,6 +505,7 @@ extern uintptr_t page_mask, page_size; extern int read_only; extern int eta_print; extern int eta_new_line; +extern unsigned int eta_interval_msec; extern unsigned long done_secs; extern int fio_gtod_offload; extern int fio_gtod_cpu; @@ -525,6 +526,8 @@ extern char *aux_path; extern struct thread_data *threads; +extern bool eta_time_within_slack(unsigned int time); + static inline void fio_ro_check(const struct thread_data *td, struct io_u *io_u) { assert(!(io_u->ddir == DDIR_WRITE && !td_write(td))); diff --git a/init.c b/init.c index b77b299e..b9da7133 100644 --- a/init.c +++ b/init.c @@ -51,6 +51,7 @@ static int nr_job_sections; int exitall_on_terminate = 0; int output_format = FIO_OUTPUT_NORMAL; int eta_print = FIO_ETA_AUTO; +unsigned int eta_interval_msec = 1000; int eta_new_line = 0; FILE *f_out = NULL; FILE *f_err = NULL; @@ -153,6 +154,11 @@ static struct option l_opts[FIO_NR_OPTIONS] = { .has_arg = required_argument, .val = 'e' | FIO_CLIENT_FLAG, }, + { + .name = (char *) "eta-interval", + .has_arg = required_argument, + .val = 'O' | FIO_CLIENT_FLAG, + }, { .name = (char *) "eta-newline", .has_arg = required_argument, @@ -2504,8 +2510,31 @@ int parse_cmd_line(int argc, char *argv[], int client_type) log_err("fio: failed parsing eta time %s\n", optarg); exit_val = 1; do_exit++; + break; } eta_new_line = t / 1000; + if (!eta_new_line) { + log_err("fio: eta new line time too short\n"); + exit_val = 1; + do_exit++; + } + break; + } + case 'O': { + long long t = 0; + + if (check_str_time(optarg, &t, 1)) { + log_err("fio: failed parsing eta interval %s\n", optarg); + exit_val = 1; + do_exit++; + break; + } + eta_interval_msec = t / 1000; + if (eta_interval_msec < DISK_UTIL_MSEC) { + log_err("fio: eta interval time too short (%umsec min)\n", DISK_UTIL_MSEC); + exit_val = 1; + do_exit++; + } break; } case 'd': -- 2.25.1