X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=eta.c;h=6017ca3102eb3b5795915a676e1140728b72579c;hb=ede04c27b618842e32b2a3349672f6b59a1697e1;hp=3126f217d490ba27e05abe65394be285354f77a2;hpb=4f37732a580d7983467ea1ba11f963da4e8cf06e;p=fio.git diff --git a/eta.c b/eta.c index 3126f217..6017ca31 100644 --- a/eta.c +++ b/eta.c @@ -2,8 +2,8 @@ * Status and ETA code */ #include -#include #include +#include #ifdef CONFIG_VALGRIND_DEV #include #else @@ -150,7 +150,7 @@ void eta_to_str(char *str, unsigned long eta_sec) str += sprintf(str, "%02uh:", h); str += sprintf(str, "%02um:", m); - str += sprintf(str, "%02us", s); + sprintf(str, "%02us", s); } /* @@ -178,12 +178,27 @@ static unsigned long thread_eta(struct thread_data *td) bytes_total = td->fill_device_size; } - if (td->o.zone_size && td->o.zone_skip && bytes_total) { + /* + * If io_size is set, bytes_total is an exact value that does not need + * adjustment. + */ + if (td->o.zone_size && td->o.zone_skip && bytes_total && + !fio_option_is_set(&td->o, io_size)) { unsigned int nr_zones; uint64_t zone_bytes; - zone_bytes = bytes_total + td->o.zone_size + td->o.zone_skip; - nr_zones = (zone_bytes - 1) / (td->o.zone_size + td->o.zone_skip); + /* + * Calculate the upper bound of the number of zones that will + * be processed, including skipped bytes between zones. If this + * is larger than total_io_size (e.g. when --io_size or --size + * specify a small value), use the lower bound to avoid + * adjustments to a negative value that would result in a very + * large bytes_total and an incorrect eta. + */ + zone_bytes = td->o.zone_size + td->o.zone_skip; + nr_zones = (bytes_total + zone_bytes - 1) / zone_bytes; + if (bytes_total < nr_zones * td->o.zone_skip) + nr_zones = bytes_total / zone_bytes; bytes_total -= nr_zones * td->o.zone_skip; } @@ -317,7 +332,7 @@ static void calc_rate(int unified_rw_rep, unsigned long mtime, else this_rate = 0; - if (unified_rw_rep) { + if (unified_rw_rep == UNIFIED_MIXED) { rate[i] = 0; rate[0] += this_rate; } else @@ -342,7 +357,7 @@ static void calc_iops(int unified_rw_rep, unsigned long mtime, else this_iops = 0; - if (unified_rw_rep) { + if (unified_rw_rep == UNIFIED_MIXED) { iops[i] = 0; iops[0] += this_iops; } else @@ -369,8 +384,8 @@ bool calc_thread_status(struct jobs_eta *je, int force) struct thread_data *td; int i, unified_rw_rep; uint64_t rate_time, disp_time, bw_avg_time, *eta_secs; - unsigned long long io_bytes[DDIR_RWDIR_CNT]; - unsigned long long io_iops[DDIR_RWDIR_CNT]; + unsigned long long io_bytes[DDIR_RWDIR_CNT] = {}; + unsigned long long io_iops[DDIR_RWDIR_CNT] = {}; struct timespec now; static unsigned long long rate_io_bytes[DDIR_RWDIR_CNT]; @@ -399,8 +414,6 @@ bool calc_thread_status(struct jobs_eta *je, int force) je->elapsed_sec = (mtime_since_genesis() + 999) / 1000; - io_bytes[DDIR_READ] = io_bytes[DDIR_WRITE] = io_bytes[DDIR_TRIM] = 0; - io_iops[DDIR_READ] = io_iops[DDIR_WRITE] = io_iops[DDIR_TRIM] = 0; bw_avg_time = ULONG_MAX; unified_rw_rep = 0; for_each_td(td, i) { @@ -408,6 +421,7 @@ bool calc_thread_status(struct jobs_eta *je, int force) if (is_power_of_2(td->o.kb_base)) je->is_pow2 = 1; je->unit_base = td->o.unit_base; + je->sig_figs = td->o.sig_figs; if (td->o.bw_avg_time < bw_avg_time) bw_avg_time = td->o.bw_avg_time; if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING @@ -495,9 +509,10 @@ bool calc_thread_status(struct jobs_eta *je, int force) calc_rate(unified_rw_rep, rate_time, io_bytes, rate_io_bytes, je->rate); memcpy(&rate_prev_time, &now, sizeof(now)); - add_agg_sample(sample_val(je->rate[DDIR_READ]), DDIR_READ, 0); - add_agg_sample(sample_val(je->rate[DDIR_WRITE]), DDIR_WRITE, 0); - add_agg_sample(sample_val(je->rate[DDIR_TRIM]), DDIR_TRIM, 0); + regrow_agg_logs(); + for_each_rw_ddir(ddir) { + add_agg_sample(sample_val(je->rate[ddir]), ddir, 0); + } } disp_time = mtime_since(&disp_prev_time, &now); @@ -519,6 +534,45 @@ bool calc_thread_status(struct jobs_eta *je, int force) return true; } +static int gen_eta_str(struct jobs_eta *je, char *p, size_t left, + char **rate_str, char **iops_str) +{ + static const char c[DDIR_RWDIR_CNT] = {'r', 'w', 't'}; + bool has[DDIR_RWDIR_CNT]; + bool has_any = false; + const char *sep; + int l = 0; + + for_each_rw_ddir(ddir) { + has[ddir] = (je->rate[ddir] || je->iops[ddir]); + has_any |= has[ddir]; + } + if (!has_any) + return 0; + + l += snprintf(p + l, left - l, "["); + sep = ""; + for_each_rw_ddir(ddir) { + if (has[ddir]) { + l += snprintf(p + l, left - l, "%s%c=%s", + sep, c[ddir], rate_str[ddir]); + sep = ","; + } + } + l += snprintf(p + l, left - l, "]["); + sep = ""; + for_each_rw_ddir(ddir) { + if (has[ddir]) { + l += snprintf(p + l, left - l, "%s%c=%s", + sep, c[ddir], iops_str[ddir]); + sep = ","; + } + } + l += snprintf(p + l, left - l, " IOPS]"); + + return l; +} + void display_thread_status(struct jobs_eta *je) { static struct timespec disp_eta_new_line; @@ -548,9 +602,9 @@ void display_thread_status(struct jobs_eta *je) char *tr, *mr; mr = num2str(je->m_rate[0] + je->m_rate[1] + je->m_rate[2], - je->sig_figs, 0, je->is_pow2, N2S_BYTEPERSEC); + je->sig_figs, 1, je->is_pow2, N2S_BYTEPERSEC); tr = num2str(je->t_rate[0] + je->t_rate[1] + je->t_rate[2], - je->sig_figs, 0, je->is_pow2, N2S_BYTEPERSEC); + je->sig_figs, 1, je->is_pow2, N2S_BYTEPERSEC); p += sprintf(p, ", %s-%s", mr, tr); free(tr); @@ -593,21 +647,10 @@ void display_thread_status(struct jobs_eta *je) } left = sizeof(output) - (p - output) - 1; + l = snprintf(p, left, ": [%s][%s]", je->run_str, perc_str); + l += gen_eta_str(je, p + l, left - l, rate_str, iops_str); + l += snprintf(p + l, left - l, "[eta %s]", eta_str); - if (je->rate[DDIR_TRIM] || je->iops[DDIR_TRIM]) - l = snprintf(p, left, - ": [%s][%s][r=%s,w=%s,t=%s][r=%s,w=%s,t=%s IOPS][eta %s]", - je->run_str, perc_str, rate_str[DDIR_READ], - rate_str[DDIR_WRITE], rate_str[DDIR_TRIM], - iops_str[DDIR_READ], iops_str[DDIR_WRITE], - iops_str[DDIR_TRIM], eta_str); - else - l = snprintf(p, left, - ": [%s][%s][r=%s,w=%s][r=%s,w=%s IOPS][eta %s]", - je->run_str, perc_str, - rate_str[DDIR_READ], rate_str[DDIR_WRITE], - iops_str[DDIR_READ], iops_str[DDIR_WRITE], - eta_str); /* If truncation occurred adjust l so p is on the null */ if (l >= left) l = left - 1; @@ -622,7 +665,7 @@ void display_thread_status(struct jobs_eta *je) free(iops_str[ddir]); } } - p += sprintf(p, "\r"); + sprintf(p, "\r"); printf("%s", output); @@ -665,14 +708,18 @@ void print_thread_status(void) size_t size; je = get_jobs_eta(false, &size); - if (je) + if (je) { display_thread_status(je); - - free(je); + free(je); + } } void print_status_init(int thr_number) { + struct jobs_eta_packed jep; + + compiletime_assert(sizeof(struct jobs_eta) == sizeof(jep), "jobs_eta"); + DRD_IGNORE_VAR(__run_str); __run_str[thr_number] = 'P'; update_condensed_str(__run_str, run_str);