X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=stat.c;h=a3bfe632454e4b0a2a2d5c5dcde5a4b429f4e6f5;hp=7fa601b72d0c3b2e6c449040cbe97f1ea9f60e1d;hb=0279b88017b5d21f0fcbb1b57481339735c41797;hpb=3d57c0e9b017a745c748416ce46d2a532d4bc274 diff --git a/stat.c b/stat.c index 7fa601b7..a3bfe632 100644 --- a/stat.c +++ b/stat.c @@ -18,6 +18,16 @@ struct fio_mutex *stat_mutex; +void clear_rusage_stat(struct thread_data *td) +{ + struct thread_stat *ts = &td->ts; + + fio_getrusage(&td->ru_start); + ts->usr_time = ts->sys_time = 0; + ts->ctx = 0; + ts->minf = ts->majf = 0; +} + void update_rusage_stat(struct thread_data *td) { struct thread_stat *ts = &td->ts; @@ -832,7 +842,7 @@ static void add_ddir_status_json(struct thread_stat *ts, unsigned int len, minv, maxv; int i; const char *ddirname[] = {"read", "write", "trim"}; - struct json_object *dir_object, *tmp_object, *percentile_object; + struct json_object *dir_object, *tmp_object, *percentile_object, *clat_bins_object; char buf[120]; double p_of_agg = 100.0; @@ -903,6 +913,18 @@ static void add_ddir_status_json(struct thread_stat *ts, json_object_add_value_int(percentile_object, (const char *)buf, ovals[i]); } + if (output_format & FIO_OUTPUT_JSON_PLUS) { + clat_bins_object = json_create_object(); + json_object_add_value_object(tmp_object, "bins", clat_bins_object); + for(i = 0; i < FIO_IO_U_PLAT_NR; i++) { + snprintf(buf, sizeof(buf), "%d", i); + json_object_add_value_int(clat_bins_object, (const char *)buf, ts->io_u_plat[ddir][i]); + } + json_object_add_value_int(clat_bins_object, "FIO_IO_U_PLAT_BITS", FIO_IO_U_PLAT_BITS); + json_object_add_value_int(clat_bins_object, "FIO_IO_U_PLAT_VAL", FIO_IO_U_PLAT_VAL); + json_object_add_value_int(clat_bins_object, "FIO_IO_U_PLAT_NR", FIO_IO_U_PLAT_NR); + } + if (!calc_lat(&ts->lat_stat[ddir], &min, &max, &mean, &dev)) { min = max = 0; mean = dev = 0.0; @@ -1064,8 +1086,34 @@ static void show_thread_status_terse_v3_v4(struct thread_stat *ts, log_buf(out, "\n"); } +void json_add_job_opts(struct json_object *root, const char *name, + struct flist_head *opt_list, bool num_jobs) +{ + struct json_object *dir_object; + struct flist_head *entry; + struct print_option *p; + + if (flist_empty(opt_list)) + return; + + dir_object = json_create_object(); + json_object_add_value_object(root, name, dir_object); + + flist_for_each(entry, opt_list) { + const char *pos = ""; + + p = flist_entry(entry, struct print_option, list); + if (!num_jobs && !strcmp(p->name, "numjobs")) + continue; + if (p->value) + pos = p->value; + json_object_add_value_string(dir_object, p->name, pos); + } +} + static struct json_object *show_thread_status_json(struct thread_stat *ts, - struct group_run_stats *rs) + struct group_run_stats *rs, + struct flist_head *opt_list) { struct json_object *root, *tmp; struct jobs_eta *je; @@ -1082,10 +1130,14 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts, json_object_add_value_int(root, "error", ts->error); /* ETA Info */ - je = get_jobs_eta(1, &size); - json_object_add_value_int(root, "eta", je->eta_sec); - json_object_add_value_int(root, "elapsed", je->elapsed_sec); + je = get_jobs_eta(true, &size); + if (je) { + json_object_add_value_int(root, "eta", je->eta_sec); + json_object_add_value_int(root, "elapsed", je->elapsed_sec); + } + if (opt_list) + json_add_job_opts(root, "job options", opt_list, true); add_ddir_status_json(ts, rs, DDIR_READ, root); add_ddir_status_json(ts, rs, DDIR_WRITE, root); @@ -1172,7 +1224,7 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts, if (len) { struct json_object *block, *percentile_object, *states; - int state, i; + int state; block = json_create_object(); json_object_add_value_object(root, "block", block); @@ -1216,6 +1268,7 @@ static void show_thread_status_terse(struct thread_stat *ts, struct json_object *show_thread_status(struct thread_stat *ts, struct group_run_stats *rs, + struct flist_head *opt_list, struct buf_output *out) { struct json_object *ret = NULL; @@ -1223,14 +1276,14 @@ struct json_object *show_thread_status(struct thread_stat *ts, if (output_format & FIO_OUTPUT_TERSE) show_thread_status_terse(ts, rs, out); if (output_format & FIO_OUTPUT_JSON) - ret = show_thread_status_json(ts, rs); + ret = show_thread_status_json(ts, rs, opt_list); if (output_format & FIO_OUTPUT_NORMAL) show_thread_status_normal(ts, rs, out); return ret; } -static void sum_stat(struct io_stat *dst, struct io_stat *src, int nr) +static void sum_stat(struct io_stat *dst, struct io_stat *src, bool first) { double mean, S; @@ -1245,7 +1298,7 @@ static void sum_stat(struct io_stat *dst, struct io_stat *src, int nr) * */ - if (nr == 1) { + if (first) { mean = src->mean.u.f; S = src->S.u.f; } else { @@ -1289,31 +1342,38 @@ void sum_group_stats(struct group_run_stats *dst, struct group_run_stats *src) dst->unit_base = src->unit_base; } -void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src, int nr) +void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src, + bool first) { int l, k; for (l = 0; l < DDIR_RWDIR_CNT; l++) { if (!dst->unified_rw_rep) { - sum_stat(&dst->clat_stat[l], &src->clat_stat[l], nr); - sum_stat(&dst->slat_stat[l], &src->slat_stat[l], nr); - sum_stat(&dst->lat_stat[l], &src->lat_stat[l], nr); - sum_stat(&dst->bw_stat[l], &src->bw_stat[l], nr); + sum_stat(&dst->clat_stat[l], &src->clat_stat[l], first); + sum_stat(&dst->slat_stat[l], &src->slat_stat[l], first); + sum_stat(&dst->lat_stat[l], &src->lat_stat[l], first); + sum_stat(&dst->bw_stat[l], &src->bw_stat[l], first); dst->io_bytes[l] += src->io_bytes[l]; if (dst->runtime[l] < src->runtime[l]) dst->runtime[l] = src->runtime[l]; } else { - sum_stat(&dst->clat_stat[0], &src->clat_stat[l], nr); - sum_stat(&dst->slat_stat[0], &src->slat_stat[l], nr); - sum_stat(&dst->lat_stat[0], &src->lat_stat[l], nr); - sum_stat(&dst->bw_stat[0], &src->bw_stat[l], nr); + sum_stat(&dst->clat_stat[0], &src->clat_stat[l], first); + sum_stat(&dst->slat_stat[0], &src->slat_stat[l], first); + sum_stat(&dst->lat_stat[0], &src->lat_stat[l], first); + sum_stat(&dst->bw_stat[0], &src->bw_stat[l], first); dst->io_bytes[0] += src->io_bytes[l]; if (dst->runtime[0] < src->runtime[l]) dst->runtime[0] = src->runtime[l]; + + /* + * We're summing to the same destination, so override + * 'first' after the first iteration of the loop + */ + first = false; } } @@ -1397,6 +1457,7 @@ void __show_run_stats(void) struct json_object *root = NULL; struct json_array *array = NULL; struct buf_output output[FIO_OUTPUT_NR]; + struct flist_head **opt_lists; runstats = malloc(sizeof(struct group_run_stats) * (groupid + 1)); @@ -1422,9 +1483,12 @@ void __show_run_stats(void) } threadstats = malloc(nr_ts * sizeof(struct thread_stat)); + opt_lists = malloc(nr_ts * sizeof(struct flist_head *)); - for (i = 0; i < nr_ts; i++) + for (i = 0; i < nr_ts; i++) { init_thread_stat(&threadstats[i]); + opt_lists[i] = NULL; + } j = 0; last_ts = -1; @@ -1443,6 +1507,7 @@ void __show_run_stats(void) ts->clat_percentiles = td->o.clat_percentiles; ts->percentile_precision = td->o.percentile_precision; memcpy(ts->percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list)); + opt_lists[j] = &td->opt_list; idx++; ts->members++; @@ -1508,7 +1573,7 @@ void __show_run_stats(void) for (k = 0; k < ts->nr_block_infos; k++) ts->block_infos[k] = td->ts.block_infos[k]; - sum_thread_stats(ts, &td->ts, idx); + sum_thread_stats(ts, &td->ts, idx == 1); } for (i = 0; i < nr_ts; i++) { @@ -1566,6 +1631,7 @@ void __show_run_stats(void) if (output_format & FIO_OUTPUT_NORMAL) log_buf(&output[__FIO_OUTPUT_NORMAL], "\n"); if (output_format & FIO_OUTPUT_JSON) { + struct thread_data *global; char time_buf[32]; time_t time_p; @@ -1578,28 +1644,34 @@ void __show_run_stats(void) json_object_add_value_string(root, "fio version", fio_version_string); json_object_add_value_int(root, "timestamp", time_p); json_object_add_value_string(root, "time", time_buf); + global = get_global_options(); + json_add_job_opts(root, "global options", &global->opt_list, false); array = json_create_array(); json_object_add_value_array(root, "jobs", array); } + if (is_backend) + fio_server_send_job_options(&get_global_options()->opt_list, -1U); + for (i = 0; i < nr_ts; i++) { ts = &threadstats[i]; rs = &runstats[ts->groupid]; - if (is_backend) + if (is_backend) { + fio_server_send_job_options(opt_lists[i], i); fio_server_send_ts(ts, rs); - else { + } else { if (output_format & FIO_OUTPUT_TERSE) show_thread_status_terse(ts, rs, &output[__FIO_OUTPUT_TERSE]); if (output_format & FIO_OUTPUT_JSON) { - struct json_object *tmp = show_thread_status_json(ts, rs); + struct json_object *tmp = show_thread_status_json(ts, rs, opt_lists[i]); json_array_add_value_object(array, tmp); } if (output_format & FIO_OUTPUT_NORMAL) show_thread_status_normal(ts, rs, &output[__FIO_OUTPUT_NORMAL]); } } - if (output_format & FIO_OUTPUT_JSON) { + if (!is_backend && (output_format & FIO_OUTPUT_JSON)) { /* disk util stats, if any */ show_disk_util(1, root, &output[__FIO_OUTPUT_JSON]); @@ -1635,6 +1707,7 @@ void __show_run_stats(void) log_info_flush(); free(runstats); free(threadstats); + free(opt_lists); } void show_run_stats(void)