From 691310e297f1d1c9b016d8ff36b00991ece951e7 Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Thu, 3 Feb 2022 19:28:30 +0000 Subject: [PATCH] stat: disable per prio stats where not needed In order to avoid allocating a clat_prio_stat array for threadstats that we know will never be able to contain more than a single priority, introduce a new member disable_prio_stat in struct thread_stat. The naming prefix is disable, since we want the default value to be 0 (enabled). This is because in default case, we do want sum_thread_stats() to generate a per prio stat array. Only in the case where we know that we don't want per priority stats to be generated, should this member be set to 1. Server version is intentionally not incremented, as it will be incremented in a later patch in the series. No need to bump it multiple times for the same patch series. Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal Link: https://lore.kernel.org/r/20220203192814.18552-14-Niklas.Cassel@wdc.com Signed-off-by: Jens Axboe --- client.c | 1 + rate-submit.c | 9 +++++++++ server.c | 1 + stat.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ stat.h | 1 + 5 files changed, 66 insertions(+) diff --git a/client.c b/client.c index cf082c74..d7a80f02 100644 --- a/client.c +++ b/client.c @@ -955,6 +955,7 @@ static void convert_ts(struct thread_stat *dst, struct thread_stat *src) dst->members = le32_to_cpu(src->members); dst->unified_rw_rep = le32_to_cpu(src->unified_rw_rep); dst->ioprio = le32_to_cpu(src->ioprio); + dst->disable_prio_stat = le32_to_cpu(src->disable_prio_stat); for (i = 0; i < DDIR_RWDIR_CNT; i++) { convert_io_stat(&dst->clat_stat[i], &src->clat_stat[i]); diff --git a/rate-submit.c b/rate-submit.c index 752c30a5..e3a71168 100644 --- a/rate-submit.c +++ b/rate-submit.c @@ -195,6 +195,15 @@ static void io_workqueue_exit_worker_fn(struct submit_worker *sw, struct thread_data *td = sw->priv; (*sum_cnt)++; + + /* + * io_workqueue_update_acct_fn() doesn't support per prio stats, and + * even if it did, offload can't be used with all async IO engines. + * If group reporting is set in the parent td, the group result + * generated by __show_run_stats() can still contain multiple prios + * from different offloaded jobs. + */ + sw->wq->td->ts.disable_prio_stat = 1; sum_thread_stats(&sw->wq->td->ts, &td->ts); fio_options_free(td); diff --git a/server.c b/server.c index 05b65631..6b45ff2e 100644 --- a/server.c +++ b/server.c @@ -1706,6 +1706,7 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs) p.ts.members = cpu_to_le32(ts->members); p.ts.unified_rw_rep = cpu_to_le32(ts->unified_rw_rep); p.ts.ioprio = cpu_to_le32(ts->ioprio); + p.ts.disable_prio_stat = cpu_to_le32(ts->disable_prio_stat); for (i = 0; i < DDIR_RWDIR_CNT; i++) { convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]); diff --git a/stat.c b/stat.c index baaa29f2..f783aed8 100644 --- a/stat.c +++ b/stat.c @@ -2171,6 +2171,58 @@ void init_thread_stat(struct thread_stat *ts) ts->groupid = -1; } +static void init_per_prio_stats(struct thread_stat *threadstats, int nr_ts) +{ + struct thread_data *td; + struct thread_stat *ts; + int i, j, last_ts, idx; + enum fio_ddir ddir; + + j = 0; + last_ts = -1; + idx = 0; + + /* + * Loop through all tds, if a td requires per prio stats, temporarily + * store a 1 in ts->disable_prio_stat, and then do an additional + * loop at the end where we invert the ts->disable_prio_stat values. + */ + for_each_td(td, i) { + if (!td->o.stats) + continue; + if (idx && + (!td->o.group_reporting || + (td->o.group_reporting && last_ts != td->groupid))) { + idx = 0; + j++; + } + + last_ts = td->groupid; + ts = &threadstats[j]; + + /* idx == 0 means first td in group, or td is not in a group. */ + if (idx == 0) + ts->ioprio = td->ioprio; + else if (td->ioprio != ts->ioprio) + ts->disable_prio_stat = 1; + + for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++) { + if (td->ts.clat_prio[ddir]) { + ts->disable_prio_stat = 1; + break; + } + } + + idx++; + } + + /* Loop through all dst threadstats and fixup the values. */ + for (i = 0; i < nr_ts; i++) { + ts = &threadstats[i]; + ts->disable_prio_stat = !ts->disable_prio_stat; + } +} + void __show_run_stats(void) { struct group_run_stats *runstats, *rs; @@ -2217,6 +2269,8 @@ void __show_run_stats(void) opt_lists[i] = NULL; } + init_per_prio_stats(threadstats, nr_ts); + j = 0; last_ts = -1; idx = 0; diff --git a/stat.h b/stat.h index 188c57f3..6c86fa22 100644 --- a/stat.h +++ b/stat.h @@ -174,6 +174,7 @@ struct thread_stat { char description[FIO_JOBDESC_SIZE]; uint32_t members; uint32_t unified_rw_rep; + uint32_t disable_prio_stat; /* * bandwidth and latency stats -- 2.25.1