4 * Common Block IO controller cgroup interface
6 * Based on ideas and code from CFQ, CFS and BFQ:
7 * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
9 * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
10 * Paolo Valente <paolo.valente@unimore.it>
12 * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com>
13 * Nauman Rafique <nauman@google.com>
16 #include <linux/cgroup.h>
18 #if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
20 #ifndef CONFIG_BLK_CGROUP
21 /* When blk-cgroup is a module, its subsys_id isn't a compile-time constant */
22 extern struct cgroup_subsys blkio_subsys;
23 #define blkio_subsys_id blkio_subsys.subsys_id
27 /* Total time spent (in ns) between request dispatch to the driver and
28 * request completion for IOs doen by this cgroup. This may not be
29 * accurate when NCQ is turned on. */
30 BLKIO_STAT_SERVICE_TIME = 0,
31 /* Total bytes transferred */
32 BLKIO_STAT_SERVICE_BYTES,
33 /* Total IOs serviced, post merge */
35 /* Total time spent waiting in scheduler queue in ns */
37 /* Number of IOs merged */
39 /* Number of IOs queued up */
41 /* All the single valued stats go below this */
44 #ifdef CONFIG_DEBUG_BLK_CGROUP
45 BLKIO_STAT_AVG_QUEUE_SIZE,
47 BLKIO_STAT_EMPTY_TIME,
48 BLKIO_STAT_GROUP_WAIT_TIME,
61 /* blkg state flags */
62 enum blkg_state_flags {
69 struct cgroup_subsys_state css;
72 struct hlist_head blkg_list;
75 struct blkio_group_stats {
76 /* total disk time and nr sectors dispatched by this group */
79 uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL];
80 #ifdef CONFIG_DEBUG_BLK_CGROUP
81 /* Sum of number of IOs queued across all samples */
82 uint64_t avg_queue_size_sum;
83 /* Count of samples taken for average */
84 uint64_t avg_queue_size_samples;
85 /* How many times this group has been removed from service tree */
86 unsigned long dequeue;
88 /* Total time spent waiting for it to be assigned a timeslice. */
89 uint64_t group_wait_time;
90 uint64_t start_group_wait_time;
92 /* Time spent idling for this blkio_group */
94 uint64_t start_idle_time;
96 * Total time when we have requests queued and do not contain the
97 * current active queue.
100 uint64_t start_empty_time;
106 /* An rcu protected unique identifier for the group */
108 struct hlist_node blkcg_node;
109 unsigned short blkcg_id;
110 #ifdef CONFIG_DEBUG_BLK_CGROUP
111 /* Store cgroup path */
114 /* The device MKDEV(major, minor), this group has been created for */
117 /* Need to serialize the stats in the case of reset/update */
118 spinlock_t stats_lock;
119 struct blkio_group_stats stats;
122 typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg);
123 typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg,
124 unsigned int weight);
126 struct blkio_policy_ops {
127 blkio_unlink_group_fn *blkio_unlink_group_fn;
128 blkio_update_group_weight_fn *blkio_update_group_weight_fn;
131 struct blkio_policy_type {
132 struct list_head list;
133 struct blkio_policy_ops ops;
136 /* Blkio controller policy registration */
137 extern void blkio_policy_register(struct blkio_policy_type *);
138 extern void blkio_policy_unregister(struct blkio_policy_type *);
145 struct blkio_policy_type {
148 static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { }
149 static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { }
153 #define BLKIO_WEIGHT_MIN 100
154 #define BLKIO_WEIGHT_MAX 1000
155 #define BLKIO_WEIGHT_DEFAULT 500
157 #ifdef CONFIG_DEBUG_BLK_CGROUP
158 static inline char *blkg_path(struct blkio_group *blkg)
162 void blkiocg_update_set_active_queue_stats(struct blkio_group *blkg);
163 void blkiocg_update_dequeue_stats(struct blkio_group *blkg,
164 unsigned long dequeue);
165 void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg);
166 void blkiocg_update_idle_time_stats(struct blkio_group *blkg);
167 void blkiocg_set_start_empty_time(struct blkio_group *blkg, bool ignore);
169 #define BLKG_FLAG_FNS(name) \
170 static inline void blkio_mark_blkg_##name( \
171 struct blkio_group_stats *stats) \
173 stats->flags |= (1 << BLKG_##name); \
175 static inline void blkio_clear_blkg_##name( \
176 struct blkio_group_stats *stats) \
178 stats->flags &= ~(1 << BLKG_##name); \
180 static inline int blkio_blkg_##name(struct blkio_group_stats *stats) \
182 return (stats->flags & (1 << BLKG_##name)) != 0; \
185 BLKG_FLAG_FNS(waiting)
186 BLKG_FLAG_FNS(idling)
190 static inline char *blkg_path(struct blkio_group *blkg) { return NULL; }
191 static inline void blkiocg_update_set_active_queue_stats(
192 struct blkio_group *blkg) {}
193 static inline void blkiocg_update_dequeue_stats(struct blkio_group *blkg,
194 unsigned long dequeue) {}
195 static inline void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg)
197 static inline void blkiocg_update_idle_time_stats(struct blkio_group *blkg) {}
198 static inline void blkiocg_set_start_empty_time(struct blkio_group *blkg,
202 #if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
203 extern struct blkio_cgroup blkio_root_cgroup;
204 extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup);
205 extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
206 struct blkio_group *blkg, void *key, dev_t dev);
207 extern int blkiocg_del_blkio_group(struct blkio_group *blkg);
208 extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg,
210 void blkio_group_init(struct blkio_group *blkg);
211 void blkiocg_update_timeslice_used(struct blkio_group *blkg,
213 void blkiocg_update_dispatch_stats(struct blkio_group *blkg, uint64_t bytes,
214 bool direction, bool sync);
215 void blkiocg_update_completion_stats(struct blkio_group *blkg,
216 uint64_t start_time, uint64_t io_start_time, bool direction, bool sync);
217 void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction,
219 void blkiocg_update_request_add_stats(struct blkio_group *blkg,
220 struct blkio_group *curr_blkg, bool direction, bool sync);
221 void blkiocg_update_request_remove_stats(struct blkio_group *blkg,
222 bool direction, bool sync);
225 static inline struct blkio_cgroup *
226 cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; }
228 static inline void blkio_group_init(struct blkio_group *blkg) {}
229 static inline void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
230 struct blkio_group *blkg, void *key, dev_t dev) {}
233 blkiocg_del_blkio_group(struct blkio_group *blkg) { return 0; }
235 static inline struct blkio_group *
236 blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key) { return NULL; }
237 static inline void blkiocg_update_timeslice_used(struct blkio_group *blkg,
238 unsigned long time) {}
239 static inline void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
240 uint64_t bytes, bool direction, bool sync) {}
241 static inline void blkiocg_update_completion_stats(struct blkio_group *blkg,
242 uint64_t start_time, uint64_t io_start_time, bool direction,
244 static inline void blkiocg_update_io_merged_stats(struct blkio_group *blkg,
245 bool direction, bool sync) {}
246 static inline void blkiocg_update_request_add_stats(struct blkio_group *blkg,
247 struct blkio_group *curr_blkg, bool direction, bool sync) {}
248 static inline void blkiocg_update_request_remove_stats(struct blkio_group *blkg,
249 bool direction, bool sync) {}
251 #endif /* _BLK_CGROUP_H */