* Status and ETA code
*/
#include <unistd.h>
-#include <fcntl.h>
#include <string.h>
+#ifdef CONFIG_VALGRIND_DEV
+#include <valgrind/drd.h>
+#else
+#define DRD_IGNORE_VAR(x) do { } while (0)
+#endif
#include "fio.h"
#include "lib/pow2.h"
str += sprintf(str, "%02uh:", h);
str += sprintf(str, "%02um:", m);
- str += sprintf(str, "%02us", s);
+ sprintf(str, "%02us", s);
}
/*
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;
}
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];
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) {
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);
+ for_each_rw_ddir(ddir) {
+ add_agg_sample(sample_val(je->rate[ddir]), ddir, 0, 0);
+ }
}
disp_time = mtime_since(&disp_prev_time, &now);
return true;
}
+static int gen_eta_str(struct jobs_eta *je, char *p, size_t left,
+ char **rate_str, char **iops_str)
+{
+ bool has_r = je->rate[DDIR_READ] || je->iops[DDIR_READ];
+ bool has_w = je->rate[DDIR_WRITE] || je->iops[DDIR_WRITE];
+ bool has_t = je->rate[DDIR_TRIM] || je->iops[DDIR_TRIM];
+ int l = 0;
+
+ if (!has_r && !has_w && !has_t)
+ return 0;
+
+ if (has_r) {
+ l += snprintf(p + l, left - l, "[r=%s", rate_str[DDIR_READ]);
+ if (!has_w)
+ l += snprintf(p + l, left - l, "]");
+ }
+ if (has_w) {
+ if (has_r)
+ l += snprintf(p + l, left - l, ",");
+ else
+ l += snprintf(p + l, left - l, "[");
+ l += snprintf(p + l, left - l, "w=%s", rate_str[DDIR_WRITE]);
+ if (!has_t)
+ l += snprintf(p + l, left - l, "]");
+ }
+ if (has_t) {
+ if (has_r || has_w)
+ l += snprintf(p + l, left - l, ",");
+ else if (!has_r && !has_w)
+ l += snprintf(p + l, left - l, "[");
+ l += snprintf(p + l, left - l, "t=%s]", rate_str[DDIR_TRIM]);
+ }
+ if (has_r) {
+ l += snprintf(p + l, left - l, "[r=%s", iops_str[DDIR_READ]);
+ if (!has_w)
+ l += snprintf(p + l, left - l, " IOPS]");
+ }
+ if (has_w) {
+ if (has_r)
+ l += snprintf(p + l, left - l, ",");
+ else
+ l += snprintf(p + l, left - l, "[");
+ l += snprintf(p + l, left - l, "w=%s", iops_str[DDIR_WRITE]);
+ if (!has_t)
+ l += snprintf(p + l, left - l, " IOPS]");
+ }
+ if (has_t) {
+ if (has_r || has_w)
+ l += snprintf(p + l, left - l, ",");
+ else if (!has_r && !has_w)
+ l += snprintf(p + l, left - l, "[");
+ l += snprintf(p + l, left - l, "t=%s IOPS]", iops_str[DDIR_TRIM]);
+ }
+
+ return l;
+}
+
void display_thread_status(struct jobs_eta *je)
{
static struct timespec disp_eta_new_line;
}
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;
free(iops_str[ddir]);
}
}
- p += sprintf(p, "\r");
+ sprintf(p, "\r");
printf("%s", output);
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);
}