examples: add examples for cmdprio_* IO priority options
[fio.git] / engines / cmdprio.h
CommitLineData
e9f6567a
DLM
1/*
2 * IO priority handling declarations and helper functions common to the
3 * libaio and io_uring engines.
4 */
5
6#ifndef FIO_CMDPRIO_H
7#define FIO_CMDPRIO_H
8
9#include "../fio.h"
10
11struct cmdprio {
12 unsigned int percentage[DDIR_RWDIR_CNT];
12f9d54a
DLM
13 unsigned int class[DDIR_RWDIR_CNT];
14 unsigned int level[DDIR_RWDIR_CNT];
a48f0cc7
DLM
15 unsigned int bssplit_nr[DDIR_RWDIR_CNT];
16 struct bssplit *bssplit[DDIR_RWDIR_CNT];
e9f6567a
DLM
17};
18
a48f0cc7
DLM
19static int fio_cmdprio_bssplit_ddir(struct thread_options *to, void *cb_arg,
20 enum fio_ddir ddir, char *str, bool data)
21{
22 struct cmdprio *cmdprio = cb_arg;
23 struct split split;
24 unsigned int i;
25
26 if (ddir == DDIR_TRIM)
27 return 0;
28
29 memset(&split, 0, sizeof(split));
30
31 if (split_parse_ddir(to, &split, str, data, BSSPLIT_MAX))
32 return 1;
33 if (!split.nr)
34 return 0;
35
36 cmdprio->bssplit_nr[ddir] = split.nr;
37 cmdprio->bssplit[ddir] = malloc(split.nr * sizeof(struct bssplit));
38 if (!cmdprio->bssplit[ddir])
39 return 1;
40
41 for (i = 0; i < split.nr; i++) {
42 cmdprio->bssplit[ddir][i].bs = split.val1[i];
43 if (split.val2[i] == -1U) {
44 cmdprio->bssplit[ddir][i].perc = 0;
45 } else {
46 if (split.val2[i] > 100)
47 cmdprio->bssplit[ddir][i].perc = 100;
48 else
49 cmdprio->bssplit[ddir][i].perc = split.val2[i];
50 }
51 }
52
53 return 0;
54}
55
56static int fio_cmdprio_bssplit_parse(struct thread_data *td, const char *input,
57 struct cmdprio *cmdprio)
58{
59 char *str, *p;
60 int i, ret = 0;
61
62 p = str = strdup(input);
63
64 strip_blank_front(&str);
65 strip_blank_end(str);
66
67 ret = str_split_parse(td, str, fio_cmdprio_bssplit_ddir, cmdprio, false);
68
69 if (parse_dryrun()) {
70 for (i = 0; i < DDIR_RWDIR_CNT; i++) {
71 free(cmdprio->bssplit[i]);
72 cmdprio->bssplit[i] = NULL;
73 cmdprio->bssplit_nr[i] = 0;
74 }
75 }
76
77 free(p);
78 return ret;
79}
80
81static inline int fio_cmdprio_percentage(struct cmdprio *cmdprio,
82 struct io_u *io_u)
83{
84 enum fio_ddir ddir = io_u->ddir;
85 unsigned int p = cmdprio->percentage[ddir];
86 int i;
87
88 /*
89 * If cmdprio_percentage option was specified, then use that
90 * percentage. Otherwise, use cmdprio_bssplit percentages depending
91 * on the IO size.
92 */
93 if (p)
94 return p;
95
96 for (i = 0; i < cmdprio->bssplit_nr[ddir]; i++) {
97 if (cmdprio->bssplit[ddir][i].bs == io_u->buflen)
98 return cmdprio->bssplit[ddir][i].perc;
99 }
100
101 return 0;
102}
103
e9f6567a
DLM
104static int fio_cmdprio_init(struct thread_data *td, struct cmdprio *cmdprio,
105 bool *has_cmdprio)
106{
107 struct thread_options *to = &td->o;
108 bool has_cmdprio_percentage = false;
a48f0cc7 109 bool has_cmdprio_bssplit = false;
e9f6567a
DLM
110 int i;
111
12f9d54a 112 /*
a48f0cc7
DLM
113 * If cmdprio_percentage/cmdprio_bssplit is set and cmdprio_class
114 * is not set, default to RT priority class.
12f9d54a 115 */
e9f6567a 116 for (i = 0; i < DDIR_RWDIR_CNT; i++) {
12f9d54a
DLM
117 if (cmdprio->percentage[i]) {
118 if (!cmdprio->class[i])
119 cmdprio->class[i] = IOPRIO_CLASS_RT;
e9f6567a 120 has_cmdprio_percentage = true;
12f9d54a 121 }
a48f0cc7
DLM
122 if (cmdprio->bssplit_nr[i]) {
123 if (!cmdprio->class[i])
124 cmdprio->class[i] = IOPRIO_CLASS_RT;
125 has_cmdprio_bssplit = true;
126 }
e9f6567a
DLM
127 }
128
129 /*
130 * Check for option conflicts
131 */
a48f0cc7
DLM
132 if (has_cmdprio_percentage && has_cmdprio_bssplit) {
133 log_err("%s: cmdprio_percentage and cmdprio_bssplit options "
134 "are mutually exclusive\n",
135 to->name);
136 return 1;
137 }
e9f6567a 138
a48f0cc7 139 *has_cmdprio = has_cmdprio_percentage || has_cmdprio_bssplit;
e9f6567a
DLM
140
141 return 0;
142}
143
144#endif