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