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;
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;
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) {
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;
- }
}
/*
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);
}