From: Niklas Cassel <niklas.cassel@xxxxxxx> To be able to report clat stats on a per priority granularity (instead of only high/low priority), we need a new function which allocates a clat_prio_stat array. This array will hold the clat stats for all the different priorities that will be used by the struct td. The clat_prio_stat array will eventually replace io_u_plat_high_prio, io_u_plat_low_prio, clat_high_prio_stat, and clat_low_prio_stat. A follow up patch will convert stat.c to use the new array. Signed-off-by: Niklas Cassel <niklas.cassel@xxxxxxx> --- stat.c | 40 ++++++++++++++++++++++++++++++++++++++++ stat.h | 19 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/stat.c b/stat.c index b08d2f25..9894ba7c 100644 --- a/stat.c +++ b/stat.c @@ -1995,6 +1995,46 @@ void sum_group_stats(struct group_run_stats *dst, struct group_run_stats *src) dst->sig_figs = src->sig_figs; } +/* + * Free the clat_prio_stat arrays allocated by alloc_clat_prio_stat_ddir(). + */ +void free_clat_prio_stats(struct thread_stat *ts) +{ + enum fio_ddir ddir; + + for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++) { + sfree(ts->clat_prio[ddir]); + ts->clat_prio[ddir] = NULL; + ts->nr_clat_prio[ddir] = 0; + } +} + +/* + * Allocate a clat_prio_stat array. The array has to be allocated/freed using + * smalloc/sfree, so that it is accessible by the process/thread summing the + * thread_stats. + */ +int alloc_clat_prio_stat_ddir(struct thread_stat *ts, enum fio_ddir ddir, + int nr_prios) +{ + struct clat_prio_stat *clat_prio; + int i; + + clat_prio = scalloc(nr_prios, sizeof(*ts->clat_prio[ddir])); + if (!clat_prio) { + log_err("fio: failed to alloc ts clat data\n"); + return 1; + } + + for (i = 0; i < nr_prios; i++) + clat_prio[i].clat_stat.min_val = ULONG_MAX; + + ts->clat_prio[ddir] = clat_prio; + ts->nr_clat_prio[ddir] = nr_prios; + + return 0; +} + void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src) { int k, l, m; diff --git a/stat.h b/stat.h index 711df24a..1e720ad8 100644 --- a/stat.h +++ b/stat.h @@ -158,6 +158,12 @@ enum fio_lat { FIO_LAT_CNT = 3, }; +struct clat_prio_stat { + uint64_t io_u_plat[FIO_IO_U_PLAT_NR]; + struct io_stat clat_stat; + uint32_t ioprio; +}; + struct thread_stat { char name[FIO_JOBNAME_SIZE]; char verror[FIO_VERROR_SIZE]; @@ -260,6 +266,17 @@ struct thread_stat { struct io_stat clat_high_prio_stat[DDIR_RWDIR_CNT] __attribute__((aligned(8))); struct io_stat clat_low_prio_stat[DDIR_RWDIR_CNT]; + union { + struct clat_prio_stat *clat_prio[DDIR_RWDIR_CNT]; + /* + * For FIO_NET_CMD_TS, the pointed to data will temporarily + * be stored at this offset from the start of the payload. + * (The union is also needed to pad this field on 32-bit.) + */ + uint64_t clat_prio_offset[DDIR_RWDIR_CNT]; + }; + uint32_t nr_clat_prio[DDIR_RWDIR_CNT]; + union { uint64_t *ss_iops_data; /* @@ -368,6 +385,8 @@ extern void add_bw_sample(struct thread_data *, struct io_u *, extern void add_sync_clat_sample(struct thread_stat *ts, unsigned long long nsec); extern int calc_log_samples(void); +extern void free_clat_prio_stats(struct thread_stat *); +extern int alloc_clat_prio_stat_ddir(struct thread_stat *, enum fio_ddir, int); extern void print_disk_util(struct disk_util_stat *, struct disk_util_agg *, int terse, struct buf_output *); extern void json_array_add_disk_util(struct disk_util_stat *dus, -- 2.34.1