GNU Linux-libre 4.19.211-gnu1
[releases.git] / Documentation / block / ioprio.txt
1 Block io priorities
2 ===================
3
4
5 Intro
6 -----
7
8 With the introduction of cfq v3 (aka cfq-ts or time sliced cfq), basic io
9 priorities are supported for reads on files.  This enables users to io nice
10 processes or process groups, similar to what has been possible with cpu
11 scheduling for ages.  This document mainly details the current possibilities
12 with cfq; other io schedulers do not support io priorities thus far.
13
14 Scheduling classes
15 ------------------
16
17 CFQ implements three generic scheduling classes that determine how io is
18 served for a process.
19
20 IOPRIO_CLASS_RT: This is the realtime io class. This scheduling class is given
21 higher priority than any other in the system, processes from this class are
22 given first access to the disk every time. Thus it needs to be used with some
23 care, one io RT process can starve the entire system. Within the RT class,
24 there are 8 levels of class data that determine exactly how much time this
25 process needs the disk for on each service. In the future this might change
26 to be more directly mappable to performance, by passing in a wanted data
27 rate instead.
28
29 IOPRIO_CLASS_BE: This is the best-effort scheduling class, which is the default
30 for any process that hasn't set a specific io priority. The class data
31 determines how much io bandwidth the process will get, it's directly mappable
32 to the cpu nice levels just more coarsely implemented. 0 is the highest
33 BE prio level, 7 is the lowest. The mapping between cpu nice level and io
34 nice level is determined as: io_nice = (cpu_nice + 20) / 5.
35
36 IOPRIO_CLASS_IDLE: This is the idle scheduling class, processes running at this
37 level only get io time when no one else needs the disk. The idle class has no
38 class data, since it doesn't really apply here.
39
40 Tools
41 -----
42
43 See below for a sample ionice tool. Usage:
44
45 # ionice -c<class> -n<level> -p<pid>
46
47 If pid isn't given, the current process is assumed. IO priority settings
48 are inherited on fork, so you can use ionice to start the process at a given
49 level:
50
51 # ionice -c2 -n0 /bin/ls
52
53 will run ls at the best-effort scheduling class at the highest priority.
54 For a running process, you can give the pid instead:
55
56 # ionice -c1 -n2 -p100
57
58 will change pid 100 to run at the realtime scheduling class, at priority 2.
59
60 ---> snip ionice.c tool <---
61
62 #include <stdio.h>
63 #include <stdlib.h>
64 #include <errno.h>
65 #include <getopt.h>
66 #include <unistd.h>
67 #include <sys/ptrace.h>
68 #include <asm/unistd.h>
69
70 extern int sys_ioprio_set(int, int, int);
71 extern int sys_ioprio_get(int, int);
72
73 #if defined(__i386__)
74 #define __NR_ioprio_set         289
75 #define __NR_ioprio_get         290
76 #elif defined(__ppc__)
77 #define __NR_ioprio_set         273
78 #define __NR_ioprio_get         274
79 #elif defined(__x86_64__)
80 #define __NR_ioprio_set         251
81 #define __NR_ioprio_get         252
82 #elif defined(__ia64__)
83 #define __NR_ioprio_set         1274
84 #define __NR_ioprio_get         1275
85 #else
86 #error "Unsupported arch"
87 #endif
88
89 static inline int ioprio_set(int which, int who, int ioprio)
90 {
91         return syscall(__NR_ioprio_set, which, who, ioprio);
92 }
93
94 static inline int ioprio_get(int which, int who)
95 {
96         return syscall(__NR_ioprio_get, which, who);
97 }
98
99 enum {
100         IOPRIO_CLASS_NONE,
101         IOPRIO_CLASS_RT,
102         IOPRIO_CLASS_BE,
103         IOPRIO_CLASS_IDLE,
104 };
105
106 enum {
107         IOPRIO_WHO_PROCESS = 1,
108         IOPRIO_WHO_PGRP,
109         IOPRIO_WHO_USER,
110 };
111
112 #define IOPRIO_CLASS_SHIFT      13
113
114 const char *to_prio[] = { "none", "realtime", "best-effort", "idle", };
115
116 int main(int argc, char *argv[])
117 {
118         int ioprio = 4, set = 0, ioprio_class = IOPRIO_CLASS_BE;
119         int c, pid = 0;
120
121         while ((c = getopt(argc, argv, "+n:c:p:")) != EOF) {
122                 switch (c) {
123                 case 'n':
124                         ioprio = strtol(optarg, NULL, 10);
125                         set = 1;
126                         break;
127                 case 'c':
128                         ioprio_class = strtol(optarg, NULL, 10);
129                         set = 1;
130                         break;
131                 case 'p':
132                         pid = strtol(optarg, NULL, 10);
133                         break;
134                 }
135         }
136
137         switch (ioprio_class) {
138                 case IOPRIO_CLASS_NONE:
139                         ioprio_class = IOPRIO_CLASS_BE;
140                         break;
141                 case IOPRIO_CLASS_RT:
142                 case IOPRIO_CLASS_BE:
143                         break;
144                 case IOPRIO_CLASS_IDLE:
145                         ioprio = 7;
146                         break;
147                 default:
148                         printf("bad prio class %d\n", ioprio_class);
149                         return 1;
150         }
151
152         if (!set) {
153                 if (!pid && argv[optind])
154                         pid = strtol(argv[optind], NULL, 10);
155
156                 ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid);
157
158                 printf("pid=%d, %d\n", pid, ioprio);
159
160                 if (ioprio == -1)
161                         perror("ioprio_get");
162                 else {
163                         ioprio_class = ioprio >> IOPRIO_CLASS_SHIFT;
164                         ioprio = ioprio & 0xff;
165                         printf("%s: prio %d\n", to_prio[ioprio_class], ioprio);
166                 }
167         } else {
168                 if (ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio | ioprio_class << IOPRIO_CLASS_SHIFT) == -1) {
169                         perror("ioprio_set");
170                         return 1;
171                 }
172
173                 if (argv[optind])
174                         execvp(argv[optind], &argv[optind]);
175         }
176
177         return 0;
178 }
179
180 ---> snip ionice.c tool <---
181
182
183 March 11 2005, Jens Axboe <jens.axboe@oracle.com>