On Thu, Jul 06, 2023 at 07:12:59AM +0900, Damien Le Moal wrote: > From: Damien Le Moal <damien.lemoal@xxxxxxxxxxxxxxxxxx> > > Add initial support for Linux to allow specifying a hint for any > priority value. With this change, a priority value becomes the > combination of a priority class, a priority level and a hint. > The generic os.h ioprio manipulation macros, as well as the > os-dragonfly.h ioprio manipulation macros are modified to ignore this > hint. > > Signed-off-by: Damien Le Moal <damien.lemoal@xxxxxxxxxxxxxxxxxx> > --- > backend.c | 5 +++-- > engines/cmdprio.c | 4 ++-- > options.c | 2 +- > os/os-dragonfly.h | 4 ++-- > os/os-linux.h | 17 +++++++++++++---- > os/os.h | 4 ++-- > 6 files changed, 23 insertions(+), 13 deletions(-) > > diff --git a/backend.c b/backend.c > index d67a4a07..6641441c 100644 > --- a/backend.c > +++ b/backend.c > @@ -1791,12 +1791,13 @@ static void *thread_main(void *data) > /* ioprio_set() has to be done before td_io_init() */ > if (fio_option_is_set(o, ioprio) || > fio_option_is_set(o, ioprio_class)) { > - ret = ioprio_set(IOPRIO_WHO_PROCESS, 0, o->ioprio_class, o->ioprio); > + ret = ioprio_set(IOPRIO_WHO_PROCESS, 0, o->ioprio_class, > + o->ioprio, 0); > if (ret == -1) { > td_verror(td, errno, "ioprio_set"); > goto err; > } > - td->ioprio = ioprio_value(o->ioprio_class, o->ioprio); > + td->ioprio = ioprio_value(o->ioprio_class, o->ioprio, 0); > td->ts.ioprio = td->ioprio; > } > > diff --git a/engines/cmdprio.c b/engines/cmdprio.c > index 979a81b6..e6ff1fc2 100644 > --- a/engines/cmdprio.c > +++ b/engines/cmdprio.c > @@ -342,7 +342,7 @@ static int fio_cmdprio_gen_perc(struct thread_data *td, struct cmdprio *cmdprio) > prio = &cmdprio->perc_entry[ddir]; > prio->perc = options->percentage[ddir]; > prio->prio = ioprio_value(options->class[ddir], > - options->level[ddir]); > + options->level[ddir], 0); > assign_clat_prio_index(prio, &values[ddir]); > > ret = init_ts_clat_prio(ts, ddir, &values[ddir]); > @@ -400,7 +400,7 @@ static int fio_cmdprio_parse_and_gen_bssplit(struct thread_data *td, > goto err; > > implicit_cmdprio = ioprio_value(options->class[ddir], > - options->level[ddir]); > + options->level[ddir], 0); > > ret = fio_cmdprio_generate_bsprio_desc(&cmdprio->bsprio_desc[ddir], > &parse_res[ddir], > diff --git a/options.c b/options.c > index a7c4ef6e..c5343d4b 100644 > --- a/options.c > +++ b/options.c > @@ -344,7 +344,7 @@ static int parse_cmdprio_bssplit_entry(struct thread_options *o, > case 4: /* bs/perc/class/level case */ > class = min(class, (unsigned int) IOPRIO_MAX_PRIO_CLASS); > level = min(level, (unsigned int) IOPRIO_MAX_PRIO); > - entry->prio = ioprio_value(class, level); > + entry->prio = ioprio_value(class, level, 0); > break; > default: > log_err("fio: invalid cmdprio_bssplit format\n"); > diff --git a/os/os-dragonfly.h b/os/os-dragonfly.h > index bde39101..4ce72539 100644 > --- a/os/os-dragonfly.h > +++ b/os/os-dragonfly.h > @@ -171,8 +171,8 @@ static inline int fio_getaffinity(int pid, os_cpu_mask_t *mask) > * ioprio_set() with 4 arguments, so define fio's ioprio_set() as a macro. > * Note that there is no idea of class within ioprio_set(2) unlike Linux. > */ > -#define ioprio_value(ioprio_class, ioprio) (ioprio) > -#define ioprio_set(which, who, ioprio_class, ioprio) \ > +#define ioprio_value(ioprio_class, ioprio, ioprio_hint) (ioprio) > +#define ioprio_set(which, who, ioprio_class, ioprio, ioprio_hint) \ > ioprio_set(which, who, ioprio) > > #define ioprio(ioprio) (ioprio) > diff --git a/os/os-linux.h b/os/os-linux.h > index 2f9f7e79..6f241d09 100644 > --- a/os/os-linux.h > +++ b/os/os-linux.h > @@ -125,13 +125,19 @@ enum { > #define IOPRIO_BITS 16 > #define IOPRIO_CLASS_SHIFT 13 > > +#define IOPRIO_HINT_BITS 10 > +#define IOPRIO_HINT_SHIFT 3 > + > #define IOPRIO_MIN_PRIO 0 /* highest priority */ > #define IOPRIO_MAX_PRIO 7 /* lowest priority */ > > #define IOPRIO_MIN_PRIO_CLASS 0 > #define IOPRIO_MAX_PRIO_CLASS 3 > > -static inline int ioprio_value(int ioprio_class, int ioprio) > +#define IOPRIO_MIN_PRIO_HINT 0 > +#define IOPRIO_MAX_PRIO_HINT ((1 << IOPRIO_HINT_BITS) - 1) > + > +static inline int ioprio_value(int ioprio_class, int ioprio, int ioprio_hint) > { > /* > * If no class is set, assume BE > @@ -139,7 +145,9 @@ static inline int ioprio_value(int ioprio_class, int ioprio) > if (!ioprio_class) > ioprio_class = IOPRIO_CLASS_BE; > > - return (ioprio_class << IOPRIO_CLASS_SHIFT) | ioprio; > + return (ioprio_class << IOPRIO_CLASS_SHIFT) | > + (ioprio_hint << IOPRIO_HINT_SHIFT) | > + ioprio; > } > > static inline bool ioprio_value_is_class_rt(unsigned int priority) > @@ -147,10 +155,11 @@ static inline bool ioprio_value_is_class_rt(unsigned int priority) > return (priority >> IOPRIO_CLASS_SHIFT) == IOPRIO_CLASS_RT; > } > > -static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio) > +static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio, > + int ioprio_hint) > { > return syscall(__NR_ioprio_set, which, who, > - ioprio_value(ioprio_class, ioprio)); > + ioprio_value(ioprio_class, ioprio, ioprio_hint)); > } > > #define ioprio_class(ioprio) ((ioprio) >> IOPRIO_CLASS_SHIFT) > diff --git a/os/os.h b/os/os.h > index 036fc233..2217d5f8 100644 > --- a/os/os.h > +++ b/os/os.h > @@ -122,9 +122,9 @@ extern int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu); > #define IOPRIO_MAX_PRIO_CLASS 0 > #endif > #ifndef FIO_HAVE_IOPRIO > -#define ioprio_value(prioclass, prio) (0) > +#define ioprio_value(prioclass, prio, priohint) (0) > #define ioprio(ioprio) 0 > -#define ioprio_set(which, who, prioclass, prio) (0) > +#define ioprio_set(which, who, prioclass, prio, priohint) (0) > #define IOPRIO_MIN_PRIO 0 > #define IOPRIO_MAX_PRIO 0 > #endif > -- > 2.41.0 > Reviewed-by: Niklas Cassel <niklas.cassel@xxxxxxx>