X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=engines%2Fcmdprio.c;h=92b752aecd413d5085249bd880502ab49e6609f6;hb=fab60fa78a1832c17f8bb200292ded4a8b3eb2a5;hp=d36b6264e07d1dfb735ee2efb3ef2b735b8021a2;hpb=127715b61286b1b77cd2c3fe7efacc01d71222ea;p=fio.git diff --git a/engines/cmdprio.c b/engines/cmdprio.c index d36b6264..92b752ae 100644 --- a/engines/cmdprio.c +++ b/engines/cmdprio.c @@ -46,22 +46,15 @@ int fio_cmdprio_bssplit_parse(struct thread_data *td, const char *input, struct cmdprio *cmdprio) { char *str, *p; - int i, ret = 0; + int ret = 0; p = str = strdup(input); strip_blank_front(&str); strip_blank_end(str); - ret = str_split_parse(td, str, fio_cmdprio_bssplit_ddir, cmdprio, false); - - if (parse_dryrun()) { - for (i = 0; i < CMDPRIO_RWDIR_CNT; i++) { - free(cmdprio->bssplit[i]); - cmdprio->bssplit[i] = NULL; - cmdprio->bssplit_nr[i] = 0; - } - } + ret = str_split_parse(td, str, fio_cmdprio_bssplit_ddir, cmdprio, + false); free(p); return ret; @@ -70,20 +63,24 @@ int fio_cmdprio_bssplit_parse(struct thread_data *td, const char *input, static int fio_cmdprio_percentage(struct cmdprio *cmdprio, struct io_u *io_u) { enum fio_ddir ddir = io_u->ddir; - unsigned int p = cmdprio->percentage[ddir]; + struct cmdprio_options *options = cmdprio->options; int i; - /* - * If cmdprio_percentage option was specified, then use that - * percentage. Otherwise, use cmdprio_bssplit percentages depending - * on the IO size. - */ - if (p) - return p; - - for (i = 0; i < cmdprio->bssplit_nr[ddir]; i++) { - if (cmdprio->bssplit[ddir][i].bs == io_u->buflen) - return cmdprio->bssplit[ddir][i].perc; + switch (cmdprio->mode) { + case CMDPRIO_MODE_PERC: + return options->percentage[ddir]; + case CMDPRIO_MODE_BSSPLIT: + for (i = 0; i < cmdprio->bssplit_nr[ddir]; i++) { + if (cmdprio->bssplit[ddir][i].bs == io_u->buflen) + return cmdprio->bssplit[ddir][i].perc; + } + break; + default: + /* + * An I/O engine should never call this function if cmdprio + * is not is use. + */ + assert(0); } return 0; @@ -104,10 +101,12 @@ bool fio_cmdprio_set_ioprio(struct thread_data *td, struct cmdprio *cmdprio, struct io_u *io_u) { enum fio_ddir ddir = io_u->ddir; - unsigned int p = fio_cmdprio_percentage(cmdprio, io_u); + struct cmdprio_options *options = cmdprio->options; + unsigned int p; unsigned int cmdprio_value = - ioprio_value(cmdprio->class[ddir], cmdprio->level[ddir]); + ioprio_value(options->class[ddir], options->level[ddir]); + p = fio_cmdprio_percentage(cmdprio, io_u); if (p && rand_between(&td->prio_state, 0, 99) < p) { io_u->ioprio = cmdprio_value; if (!td->ioprio || cmdprio_value < td->ioprio) { @@ -134,29 +133,89 @@ bool fio_cmdprio_set_ioprio(struct thread_data *td, struct cmdprio *cmdprio, return false; } +static int fio_cmdprio_parse_and_gen_bssplit(struct thread_data *td, + struct cmdprio *cmdprio) +{ + struct cmdprio_options *options = cmdprio->options; + int ret; + + ret = fio_cmdprio_bssplit_parse(td, options->bssplit_str, cmdprio); + if (ret) + goto err; + + return 0; + +err: + fio_cmdprio_cleanup(cmdprio); + + return ret; +} + +static int fio_cmdprio_parse_and_gen(struct thread_data *td, + struct cmdprio *cmdprio) +{ + struct cmdprio_options *options = cmdprio->options; + int i, ret; + + switch (cmdprio->mode) { + case CMDPRIO_MODE_BSSPLIT: + ret = fio_cmdprio_parse_and_gen_bssplit(td, cmdprio); + break; + case CMDPRIO_MODE_PERC: + ret = 0; + break; + default: + assert(0); + return 1; + } + + /* + * If cmdprio_percentage/cmdprio_bssplit is set and cmdprio_class + * is not set, default to RT priority class. + */ + for (i = 0; i < CMDPRIO_RWDIR_CNT; i++) { + if (options->percentage[i] || cmdprio->bssplit_nr[i]) { + if (!options->class[i]) + options->class[i] = IOPRIO_CLASS_RT; + } + } + + return ret; +} + +void fio_cmdprio_cleanup(struct cmdprio *cmdprio) +{ + int ddir; + + for (ddir = 0; ddir < CMDPRIO_RWDIR_CNT; ddir++) { + free(cmdprio->bssplit[ddir]); + cmdprio->bssplit[ddir] = NULL; + cmdprio->bssplit_nr[ddir] = 0; + } + + /* + * options points to a cmdprio_options struct that is part of td->eo. + * td->eo itself will be freed by free_ioengine(). + */ + cmdprio->options = NULL; +} + int fio_cmdprio_init(struct thread_data *td, struct cmdprio *cmdprio, - bool *has_cmdprio) + struct cmdprio_options *options) { struct thread_options *to = &td->o; bool has_cmdprio_percentage = false; bool has_cmdprio_bssplit = false; int i; - /* - * If cmdprio_percentage/cmdprio_bssplit is set and cmdprio_class - * is not set, default to RT priority class. - */ + cmdprio->options = options; + + if (options->bssplit_str && strlen(options->bssplit_str)) + has_cmdprio_bssplit = true; + for (i = 0; i < CMDPRIO_RWDIR_CNT; i++) { - if (cmdprio->percentage[i]) { - if (!cmdprio->class[i]) - cmdprio->class[i] = IOPRIO_CLASS_RT; + if (options->percentage[i]) has_cmdprio_percentage = true; - } - if (cmdprio->bssplit_nr[i]) { - if (!cmdprio->class[i]) - cmdprio->class[i] = IOPRIO_CLASS_RT; - has_cmdprio_bssplit = true; - } } /* @@ -169,7 +228,16 @@ int fio_cmdprio_init(struct thread_data *td, struct cmdprio *cmdprio, return 1; } - *has_cmdprio = has_cmdprio_percentage || has_cmdprio_bssplit; + if (has_cmdprio_bssplit) + cmdprio->mode = CMDPRIO_MODE_BSSPLIT; + else if (has_cmdprio_percentage) + cmdprio->mode = CMDPRIO_MODE_PERC; + else + cmdprio->mode = CMDPRIO_MODE_NONE; - return 0; + /* Nothing left to do if cmdprio is not used */ + if (cmdprio->mode == CMDPRIO_MODE_NONE) + return 0; + + return fio_cmdprio_parse_and_gen(td, cmdprio); }