On 2/1/22 06:13, Niklas Cassel wrote: > 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"); Nit: s/alloc/allocate > + 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, With the nit fixed, Reviewed-by: Damien Le Moal <damien.lemoal@xxxxxxxxxxxxxxxxxx> -- Damien Le Moal Western Digital Research