]> git.karo-electronics.de Git - karo-tx-linux.git/blob - block/blk-cgroup.h
blkcg: make blkg_conf_prep() take @pol and return with queue lock held
[karo-tx-linux.git] / block / blk-cgroup.h
1 #ifndef _BLK_CGROUP_H
2 #define _BLK_CGROUP_H
3 /*
4  * Common Block IO controller cgroup interface
5  *
6  * Based on ideas and code from CFQ, CFS and BFQ:
7  * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
8  *
9  * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
10  *                    Paolo Valente <paolo.valente@unimore.it>
11  *
12  * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com>
13  *                    Nauman Rafique <nauman@google.com>
14  */
15
16 #include <linux/cgroup.h>
17 #include <linux/u64_stats_sync.h>
18 #include <linux/seq_file.h>
19
20 /* Max limits for throttle policy */
21 #define THROTL_IOPS_MAX         UINT_MAX
22
23 /* CFQ specific, out here for blkcg->cfq_weight */
24 #define CFQ_WEIGHT_MIN          10
25 #define CFQ_WEIGHT_MAX          1000
26 #define CFQ_WEIGHT_DEFAULT      500
27
28 #ifdef CONFIG_BLK_CGROUP
29
30 enum blkg_rwstat_type {
31         BLKG_RWSTAT_READ,
32         BLKG_RWSTAT_WRITE,
33         BLKG_RWSTAT_SYNC,
34         BLKG_RWSTAT_ASYNC,
35
36         BLKG_RWSTAT_NR,
37         BLKG_RWSTAT_TOTAL = BLKG_RWSTAT_NR,
38 };
39
40 struct blkio_cgroup {
41         struct cgroup_subsys_state css;
42         spinlock_t lock;
43         struct hlist_head blkg_list;
44
45         /* for policies to test whether associated blkcg has changed */
46         uint64_t id;
47
48         /* TODO: per-policy storage in blkio_cgroup */
49         unsigned int cfq_weight;        /* belongs to cfq */
50 };
51
52 struct blkg_stat {
53         struct u64_stats_sync           syncp;
54         uint64_t                        cnt;
55 };
56
57 struct blkg_rwstat {
58         struct u64_stats_sync           syncp;
59         uint64_t                        cnt[BLKG_RWSTAT_NR];
60 };
61
62 /* per-blkg per-policy data */
63 struct blkg_policy_data {
64         /* the blkg this per-policy data belongs to */
65         struct blkio_group *blkg;
66
67         /* pol->pdata_size bytes of private data used by policy impl */
68         char pdata[] __aligned(__alignof__(unsigned long long));
69 };
70
71 struct blkio_group {
72         /* Pointer to the associated request_queue */
73         struct request_queue *q;
74         struct list_head q_node;
75         struct hlist_node blkcg_node;
76         struct blkio_cgroup *blkcg;
77         /* Store cgroup path */
78         char path[128];
79         /* reference count */
80         int refcnt;
81
82         struct blkg_policy_data *pd[BLKCG_MAX_POLS];
83
84         struct rcu_head rcu_head;
85 };
86
87 typedef void (blkio_init_group_fn)(struct blkio_group *blkg);
88 typedef void (blkio_exit_group_fn)(struct blkio_group *blkg);
89 typedef void (blkio_reset_group_stats_fn)(struct blkio_group *blkg);
90
91 struct blkio_policy_ops {
92         blkio_init_group_fn *blkio_init_group_fn;
93         blkio_exit_group_fn *blkio_exit_group_fn;
94         blkio_reset_group_stats_fn *blkio_reset_group_stats_fn;
95 };
96
97 struct blkio_policy_type {
98         struct blkio_policy_ops ops;
99         int plid;
100         size_t pdata_size;              /* policy specific private data size */
101         struct cftype *cftypes;         /* cgroup files for the policy */
102 };
103
104 extern int blkcg_init_queue(struct request_queue *q);
105 extern void blkcg_drain_queue(struct request_queue *q);
106 extern void blkcg_exit_queue(struct request_queue *q);
107
108 /* Blkio controller policy registration */
109 extern int blkio_policy_register(struct blkio_policy_type *);
110 extern void blkio_policy_unregister(struct blkio_policy_type *);
111 extern void blkg_destroy_all(struct request_queue *q, bool destroy_root);
112 extern void update_root_blkg_pd(struct request_queue *q,
113                                 const struct blkio_policy_type *pol);
114
115 void blkcg_print_blkgs(struct seq_file *sf, struct blkio_cgroup *blkcg,
116                        u64 (*prfill)(struct seq_file *, void *, int),
117                        const struct blkio_policy_type *pol, int data,
118                        bool show_total);
119 u64 __blkg_prfill_u64(struct seq_file *sf, void *pdata, u64 v);
120 u64 __blkg_prfill_rwstat(struct seq_file *sf, void *pdata,
121                          const struct blkg_rwstat *rwstat);
122 u64 blkg_prfill_stat(struct seq_file *sf, void *pdata, int off);
123 u64 blkg_prfill_rwstat(struct seq_file *sf, void *pdata, int off);
124
125 struct blkg_conf_ctx {
126         struct gendisk          *disk;
127         struct blkio_group      *blkg;
128         u64                     v;
129 };
130
131 int blkg_conf_prep(struct blkio_cgroup *blkcg,
132                    const struct blkio_policy_type *pol, const char *input,
133                    struct blkg_conf_ctx *ctx);
134 void blkg_conf_finish(struct blkg_conf_ctx *ctx);
135
136
137 /**
138  * blkg_to_pdata - get policy private data
139  * @blkg: blkg of interest
140  * @pol: policy of interest
141  *
142  * Return pointer to private data associated with the @blkg-@pol pair.
143  */
144 static inline void *blkg_to_pdata(struct blkio_group *blkg,
145                               struct blkio_policy_type *pol)
146 {
147         return blkg ? blkg->pd[pol->plid]->pdata : NULL;
148 }
149
150 /**
151  * pdata_to_blkg - get blkg associated with policy private data
152  * @pdata: policy private data of interest
153  *
154  * @pdata is policy private data.  Determine the blkg it's associated with.
155  */
156 static inline struct blkio_group *pdata_to_blkg(void *pdata)
157 {
158         if (pdata) {
159                 struct blkg_policy_data *pd =
160                         container_of(pdata, struct blkg_policy_data, pdata);
161                 return pd->blkg;
162         }
163         return NULL;
164 }
165
166 static inline char *blkg_path(struct blkio_group *blkg)
167 {
168         return blkg->path;
169 }
170
171 /**
172  * blkg_get - get a blkg reference
173  * @blkg: blkg to get
174  *
175  * The caller should be holding queue_lock and an existing reference.
176  */
177 static inline void blkg_get(struct blkio_group *blkg)
178 {
179         lockdep_assert_held(blkg->q->queue_lock);
180         WARN_ON_ONCE(!blkg->refcnt);
181         blkg->refcnt++;
182 }
183
184 void __blkg_release(struct blkio_group *blkg);
185
186 /**
187  * blkg_put - put a blkg reference
188  * @blkg: blkg to put
189  *
190  * The caller should be holding queue_lock.
191  */
192 static inline void blkg_put(struct blkio_group *blkg)
193 {
194         lockdep_assert_held(blkg->q->queue_lock);
195         WARN_ON_ONCE(blkg->refcnt <= 0);
196         if (!--blkg->refcnt)
197                 __blkg_release(blkg);
198 }
199
200 /**
201  * blkg_stat_add - add a value to a blkg_stat
202  * @stat: target blkg_stat
203  * @val: value to add
204  *
205  * Add @val to @stat.  The caller is responsible for synchronizing calls to
206  * this function.
207  */
208 static inline void blkg_stat_add(struct blkg_stat *stat, uint64_t val)
209 {
210         u64_stats_update_begin(&stat->syncp);
211         stat->cnt += val;
212         u64_stats_update_end(&stat->syncp);
213 }
214
215 /**
216  * blkg_stat_read - read the current value of a blkg_stat
217  * @stat: blkg_stat to read
218  *
219  * Read the current value of @stat.  This function can be called without
220  * synchroniztion and takes care of u64 atomicity.
221  */
222 static inline uint64_t blkg_stat_read(struct blkg_stat *stat)
223 {
224         unsigned int start;
225         uint64_t v;
226
227         do {
228                 start = u64_stats_fetch_begin(&stat->syncp);
229                 v = stat->cnt;
230         } while (u64_stats_fetch_retry(&stat->syncp, start));
231
232         return v;
233 }
234
235 /**
236  * blkg_stat_reset - reset a blkg_stat
237  * @stat: blkg_stat to reset
238  */
239 static inline void blkg_stat_reset(struct blkg_stat *stat)
240 {
241         stat->cnt = 0;
242 }
243
244 /**
245  * blkg_rwstat_add - add a value to a blkg_rwstat
246  * @rwstat: target blkg_rwstat
247  * @rw: mask of REQ_{WRITE|SYNC}
248  * @val: value to add
249  *
250  * Add @val to @rwstat.  The counters are chosen according to @rw.  The
251  * caller is responsible for synchronizing calls to this function.
252  */
253 static inline void blkg_rwstat_add(struct blkg_rwstat *rwstat,
254                                    int rw, uint64_t val)
255 {
256         u64_stats_update_begin(&rwstat->syncp);
257
258         if (rw & REQ_WRITE)
259                 rwstat->cnt[BLKG_RWSTAT_WRITE] += val;
260         else
261                 rwstat->cnt[BLKG_RWSTAT_READ] += val;
262         if (rw & REQ_SYNC)
263                 rwstat->cnt[BLKG_RWSTAT_SYNC] += val;
264         else
265                 rwstat->cnt[BLKG_RWSTAT_ASYNC] += val;
266
267         u64_stats_update_end(&rwstat->syncp);
268 }
269
270 /**
271  * blkg_rwstat_read - read the current values of a blkg_rwstat
272  * @rwstat: blkg_rwstat to read
273  *
274  * Read the current snapshot of @rwstat and return it as the return value.
275  * This function can be called without synchronization and takes care of
276  * u64 atomicity.
277  */
278 static struct blkg_rwstat blkg_rwstat_read(struct blkg_rwstat *rwstat)
279 {
280         unsigned int start;
281         struct blkg_rwstat tmp;
282
283         do {
284                 start = u64_stats_fetch_begin(&rwstat->syncp);
285                 tmp = *rwstat;
286         } while (u64_stats_fetch_retry(&rwstat->syncp, start));
287
288         return tmp;
289 }
290
291 /**
292  * blkg_rwstat_sum - read the total count of a blkg_rwstat
293  * @rwstat: blkg_rwstat to read
294  *
295  * Return the total count of @rwstat regardless of the IO direction.  This
296  * function can be called without synchronization and takes care of u64
297  * atomicity.
298  */
299 static inline uint64_t blkg_rwstat_sum(struct blkg_rwstat *rwstat)
300 {
301         struct blkg_rwstat tmp = blkg_rwstat_read(rwstat);
302
303         return tmp.cnt[BLKG_RWSTAT_READ] + tmp.cnt[BLKG_RWSTAT_WRITE];
304 }
305
306 /**
307  * blkg_rwstat_reset - reset a blkg_rwstat
308  * @rwstat: blkg_rwstat to reset
309  */
310 static inline void blkg_rwstat_reset(struct blkg_rwstat *rwstat)
311 {
312         memset(rwstat->cnt, 0, sizeof(rwstat->cnt));
313 }
314
315 #else
316
317 struct blkio_group {
318 };
319
320 struct blkio_policy_type {
321 };
322
323 static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
324 static inline void blkcg_drain_queue(struct request_queue *q) { }
325 static inline void blkcg_exit_queue(struct request_queue *q) { }
326 static inline int blkio_policy_register(struct blkio_policy_type *blkiop) { return 0; }
327 static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { }
328 static inline void blkg_destroy_all(struct request_queue *q,
329                                     bool destory_root) { }
330 static inline void update_root_blkg_pd(struct request_queue *q,
331                                        const struct blkio_policy_type *pol) { }
332
333 static inline void *blkg_to_pdata(struct blkio_group *blkg,
334                                 struct blkio_policy_type *pol) { return NULL; }
335 static inline struct blkio_group *pdata_to_blkg(void *pdata,
336                                 struct blkio_policy_type *pol) { return NULL; }
337 static inline char *blkg_path(struct blkio_group *blkg) { return NULL; }
338 static inline void blkg_get(struct blkio_group *blkg) { }
339 static inline void blkg_put(struct blkio_group *blkg) { }
340
341 #endif
342
343 #ifdef CONFIG_BLK_CGROUP
344 extern struct blkio_cgroup blkio_root_cgroup;
345 extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup);
346 extern struct blkio_cgroup *bio_blkio_cgroup(struct bio *bio);
347 extern struct blkio_group *blkg_lookup(struct blkio_cgroup *blkcg,
348                                        struct request_queue *q);
349 struct blkio_group *blkg_lookup_create(struct blkio_cgroup *blkcg,
350                                        struct request_queue *q,
351                                        bool for_root);
352 #else
353 struct cgroup;
354 static inline struct blkio_cgroup *
355 cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; }
356 static inline struct blkio_cgroup *
357 bio_blkio_cgroup(struct bio *bio) { return NULL; }
358
359 static inline struct blkio_group *blkg_lookup(struct blkio_cgroup *blkcg,
360                                               void *key) { return NULL; }
361 #endif
362 #endif /* _BLK_CGROUP_H */