xref: /linux/block/blk-cgroup.h (revision bfffa1cc9db8a950dd4b1a09999f8a20e69a6652)
131e4c28dSVivek Goyal #ifndef _BLK_CGROUP_H
231e4c28dSVivek Goyal #define _BLK_CGROUP_H
331e4c28dSVivek Goyal /*
431e4c28dSVivek Goyal  * Common Block IO controller cgroup interface
531e4c28dSVivek Goyal  *
631e4c28dSVivek Goyal  * Based on ideas and code from CFQ, CFS and BFQ:
731e4c28dSVivek Goyal  * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
831e4c28dSVivek Goyal  *
931e4c28dSVivek Goyal  * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
1031e4c28dSVivek Goyal  *		      Paolo Valente <paolo.valente@unimore.it>
1131e4c28dSVivek Goyal  *
1231e4c28dSVivek Goyal  * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com>
1331e4c28dSVivek Goyal  * 	              Nauman Rafique <nauman@google.com>
1431e4c28dSVivek Goyal  */
1531e4c28dSVivek Goyal 
1631e4c28dSVivek Goyal #include <linux/cgroup.h>
17575969a0SVivek Goyal #include <linux/u64_stats_sync.h>
18829fdb50STejun Heo #include <linux/seq_file.h>
19a637120eSTejun Heo #include <linux/radix-tree.h>
20a051661cSTejun Heo #include <linux/blkdev.h>
21a5049a8aSTejun Heo #include <linux/atomic.h>
2231e4c28dSVivek Goyal 
239355aedeSVivek Goyal /* Max limits for throttle policy */
249355aedeSVivek Goyal #define THROTL_IOPS_MAX		UINT_MAX
259355aedeSVivek Goyal 
26f48ec1d7STejun Heo #ifdef CONFIG_BLK_CGROUP
27f48ec1d7STejun Heo 
28edcb0722STejun Heo enum blkg_rwstat_type {
29edcb0722STejun Heo 	BLKG_RWSTAT_READ,
30edcb0722STejun Heo 	BLKG_RWSTAT_WRITE,
31edcb0722STejun Heo 	BLKG_RWSTAT_SYNC,
32edcb0722STejun Heo 	BLKG_RWSTAT_ASYNC,
33edcb0722STejun Heo 
34edcb0722STejun Heo 	BLKG_RWSTAT_NR,
35edcb0722STejun Heo 	BLKG_RWSTAT_TOTAL = BLKG_RWSTAT_NR,
36303a3acbSDivyesh Shah };
37303a3acbSDivyesh Shah 
38a637120eSTejun Heo struct blkcg_gq;
39a637120eSTejun Heo 
403c798398STejun Heo struct blkcg {
4131e4c28dSVivek Goyal 	struct cgroup_subsys_state	css;
4231e4c28dSVivek Goyal 	spinlock_t			lock;
43a637120eSTejun Heo 
44a637120eSTejun Heo 	struct radix_tree_root		blkg_tree;
45a637120eSTejun Heo 	struct blkcg_gq			*blkg_hint;
4631e4c28dSVivek Goyal 	struct hlist_head		blkg_list;
479a9e8a26STejun Heo 
48*e48453c3SArianna Avanzini 	struct blkcg_policy_data	*pd[BLKCG_MAX_POLS];
4931e4c28dSVivek Goyal };
5031e4c28dSVivek Goyal 
51edcb0722STejun Heo struct blkg_stat {
52edf1b879STejun Heo 	struct u64_stats_sync		syncp;
53edcb0722STejun Heo 	uint64_t			cnt;
54edcb0722STejun Heo };
55edcb0722STejun Heo 
56edcb0722STejun Heo struct blkg_rwstat {
57edcb0722STejun Heo 	struct u64_stats_sync		syncp;
58edcb0722STejun Heo 	uint64_t			cnt[BLKG_RWSTAT_NR];
59edcb0722STejun Heo };
60edcb0722STejun Heo 
61f95a04afSTejun Heo /*
62f95a04afSTejun Heo  * A blkcg_gq (blkg) is association between a block cgroup (blkcg) and a
63f95a04afSTejun Heo  * request_queue (q).  This is used by blkcg policies which need to track
64f95a04afSTejun Heo  * information per blkcg - q pair.
65f95a04afSTejun Heo  *
66f95a04afSTejun Heo  * There can be multiple active blkcg policies and each has its private
67f95a04afSTejun Heo  * data on each blkg, the size of which is determined by
68f95a04afSTejun Heo  * blkcg_policy->pd_size.  blkcg core allocates and frees such areas
69f95a04afSTejun Heo  * together with blkg and invokes pd_init/exit_fn() methods.
70f95a04afSTejun Heo  *
71f95a04afSTejun Heo  * Such private data must embed struct blkg_policy_data (pd) at the
72f95a04afSTejun Heo  * beginning and pd_size can't be smaller than pd.
73f95a04afSTejun Heo  */
740381411eSTejun Heo struct blkg_policy_data {
75b276a876STejun Heo 	/* the blkg and policy id this per-policy data belongs to */
763c798398STejun Heo 	struct blkcg_gq			*blkg;
77b276a876STejun Heo 	int				plid;
780381411eSTejun Heo 
79a2b1693bSTejun Heo 	/* used during policy activation */
80a2b1693bSTejun Heo 	struct list_head		alloc_node;
810381411eSTejun Heo };
820381411eSTejun Heo 
83*e48453c3SArianna Avanzini /*
84*e48453c3SArianna Avanzini  * Policies that need to keep per-blkcg data which is independent
85*e48453c3SArianna Avanzini  * from any request_queue associated to it must specify its size
86*e48453c3SArianna Avanzini  * with the cpd_size field of the blkcg_policy structure and
87*e48453c3SArianna Avanzini  * embed a blkcg_policy_data in it. blkcg core allocates
88*e48453c3SArianna Avanzini  * policy-specific per-blkcg structures lazily the first time
89*e48453c3SArianna Avanzini  * they are actually needed, so it handles them together with
90*e48453c3SArianna Avanzini  * blkgs. cpd_init() is invoked to let each policy handle
91*e48453c3SArianna Avanzini  * per-blkcg data.
92*e48453c3SArianna Avanzini  */
93*e48453c3SArianna Avanzini struct blkcg_policy_data {
94*e48453c3SArianna Avanzini 	/* the policy id this per-policy data belongs to */
95*e48453c3SArianna Avanzini 	int				plid;
96*e48453c3SArianna Avanzini 
97*e48453c3SArianna Avanzini 	/* used during policy activation */
98*e48453c3SArianna Avanzini 	struct list_head		alloc_node;
99*e48453c3SArianna Avanzini };
100*e48453c3SArianna Avanzini 
1013c798398STejun Heo /* association between a blk cgroup and a request queue */
1023c798398STejun Heo struct blkcg_gq {
103c875f4d0STejun Heo 	/* Pointer to the associated request_queue */
104c875f4d0STejun Heo 	struct request_queue		*q;
105e8989faeSTejun Heo 	struct list_head		q_node;
10631e4c28dSVivek Goyal 	struct hlist_node		blkcg_node;
1073c798398STejun Heo 	struct blkcg			*blkcg;
1083c547865STejun Heo 
1093c547865STejun Heo 	/* all non-root blkcg_gq's are guaranteed to have access to parent */
1103c547865STejun Heo 	struct blkcg_gq			*parent;
1113c547865STejun Heo 
112a051661cSTejun Heo 	/* request allocation list for this blkcg-q pair */
113a051661cSTejun Heo 	struct request_list		rl;
1143c547865STejun Heo 
1151adaf3ddSTejun Heo 	/* reference count */
116a5049a8aSTejun Heo 	atomic_t			refcnt;
11722084190SVivek Goyal 
118f427d909STejun Heo 	/* is this blkg online? protected by both blkcg and q locks */
119f427d909STejun Heo 	bool				online;
120f427d909STejun Heo 
1218bd435b3STejun Heo 	struct blkg_policy_data		*pd[BLKCG_MAX_POLS];
1221adaf3ddSTejun Heo 
1231adaf3ddSTejun Heo 	struct rcu_head			rcu_head;
12431e4c28dSVivek Goyal };
12531e4c28dSVivek Goyal 
126*e48453c3SArianna Avanzini typedef void (blkcg_pol_init_cpd_fn)(const struct blkcg *blkcg);
1273c798398STejun Heo typedef void (blkcg_pol_init_pd_fn)(struct blkcg_gq *blkg);
128f427d909STejun Heo typedef void (blkcg_pol_online_pd_fn)(struct blkcg_gq *blkg);
129f427d909STejun Heo typedef void (blkcg_pol_offline_pd_fn)(struct blkcg_gq *blkg);
1303c798398STejun Heo typedef void (blkcg_pol_exit_pd_fn)(struct blkcg_gq *blkg);
1313c798398STejun Heo typedef void (blkcg_pol_reset_pd_stats_fn)(struct blkcg_gq *blkg);
1323e252066SVivek Goyal 
1333c798398STejun Heo struct blkcg_policy {
1348bd435b3STejun Heo 	int				plid;
13536558c8aSTejun Heo 	/* policy specific private data size */
136f95a04afSTejun Heo 	size_t				pd_size;
137*e48453c3SArianna Avanzini 	/* policy specific per-blkcg data size */
138*e48453c3SArianna Avanzini 	size_t				cpd_size;
13936558c8aSTejun Heo 	/* cgroup files for the policy */
14036558c8aSTejun Heo 	struct cftype			*cftypes;
141f9fcc2d3STejun Heo 
142f9fcc2d3STejun Heo 	/* operations */
143*e48453c3SArianna Avanzini 	blkcg_pol_init_cpd_fn		*cpd_init_fn;
144f9fcc2d3STejun Heo 	blkcg_pol_init_pd_fn		*pd_init_fn;
145f427d909STejun Heo 	blkcg_pol_online_pd_fn		*pd_online_fn;
146f427d909STejun Heo 	blkcg_pol_offline_pd_fn		*pd_offline_fn;
147f9fcc2d3STejun Heo 	blkcg_pol_exit_pd_fn		*pd_exit_fn;
148f9fcc2d3STejun Heo 	blkcg_pol_reset_pd_stats_fn	*pd_reset_stats_fn;
1493e252066SVivek Goyal };
1503e252066SVivek Goyal 
1513c798398STejun Heo extern struct blkcg blkcg_root;
15236558c8aSTejun Heo 
1533c798398STejun Heo struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, struct request_queue *q);
1543c798398STejun Heo struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
15536558c8aSTejun Heo 				    struct request_queue *q);
15636558c8aSTejun Heo int blkcg_init_queue(struct request_queue *q);
15736558c8aSTejun Heo void blkcg_drain_queue(struct request_queue *q);
15836558c8aSTejun Heo void blkcg_exit_queue(struct request_queue *q);
1595efd6113STejun Heo 
1603e252066SVivek Goyal /* Blkio controller policy registration */
161d5bf0291SJens Axboe int blkcg_policy_register(struct blkcg_policy *pol);
1623c798398STejun Heo void blkcg_policy_unregister(struct blkcg_policy *pol);
16336558c8aSTejun Heo int blkcg_activate_policy(struct request_queue *q,
1643c798398STejun Heo 			  const struct blkcg_policy *pol);
16536558c8aSTejun Heo void blkcg_deactivate_policy(struct request_queue *q,
1663c798398STejun Heo 			     const struct blkcg_policy *pol);
1673e252066SVivek Goyal 
1683c798398STejun Heo void blkcg_print_blkgs(struct seq_file *sf, struct blkcg *blkcg,
169f95a04afSTejun Heo 		       u64 (*prfill)(struct seq_file *,
170f95a04afSTejun Heo 				     struct blkg_policy_data *, int),
1713c798398STejun Heo 		       const struct blkcg_policy *pol, int data,
172ec399347STejun Heo 		       bool show_total);
173f95a04afSTejun Heo u64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v);
174f95a04afSTejun Heo u64 __blkg_prfill_rwstat(struct seq_file *sf, struct blkg_policy_data *pd,
175829fdb50STejun Heo 			 const struct blkg_rwstat *rwstat);
176f95a04afSTejun Heo u64 blkg_prfill_stat(struct seq_file *sf, struct blkg_policy_data *pd, int off);
177f95a04afSTejun Heo u64 blkg_prfill_rwstat(struct seq_file *sf, struct blkg_policy_data *pd,
178f95a04afSTejun Heo 		       int off);
179829fdb50STejun Heo 
18016b3de66STejun Heo u64 blkg_stat_recursive_sum(struct blkg_policy_data *pd, int off);
18116b3de66STejun Heo struct blkg_rwstat blkg_rwstat_recursive_sum(struct blkg_policy_data *pd,
18216b3de66STejun Heo 					     int off);
18316b3de66STejun Heo 
184829fdb50STejun Heo struct blkg_conf_ctx {
185829fdb50STejun Heo 	struct gendisk			*disk;
1863c798398STejun Heo 	struct blkcg_gq			*blkg;
187829fdb50STejun Heo 	u64				v;
188829fdb50STejun Heo };
189829fdb50STejun Heo 
1903c798398STejun Heo int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
1913c798398STejun Heo 		   const char *input, struct blkg_conf_ctx *ctx);
192829fdb50STejun Heo void blkg_conf_finish(struct blkg_conf_ctx *ctx);
193829fdb50STejun Heo 
194829fdb50STejun Heo 
195a7c6d554STejun Heo static inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *css)
196a7c6d554STejun Heo {
197a7c6d554STejun Heo 	return css ? container_of(css, struct blkcg, css) : NULL;
198a7c6d554STejun Heo }
199a7c6d554STejun Heo 
200b1208b56STejun Heo static inline struct blkcg *task_blkcg(struct task_struct *tsk)
201b1208b56STejun Heo {
202073219e9STejun Heo 	return css_to_blkcg(task_css(tsk, blkio_cgrp_id));
203b1208b56STejun Heo }
204b1208b56STejun Heo 
205b1208b56STejun Heo static inline struct blkcg *bio_blkcg(struct bio *bio)
206b1208b56STejun Heo {
207b1208b56STejun Heo 	if (bio && bio->bi_css)
208a7c6d554STejun Heo 		return css_to_blkcg(bio->bi_css);
209b1208b56STejun Heo 	return task_blkcg(current);
210b1208b56STejun Heo }
211b1208b56STejun Heo 
2120381411eSTejun Heo /**
2133c547865STejun Heo  * blkcg_parent - get the parent of a blkcg
2143c547865STejun Heo  * @blkcg: blkcg of interest
2153c547865STejun Heo  *
2163c547865STejun Heo  * Return the parent blkcg of @blkcg.  Can be called anytime.
2173c547865STejun Heo  */
2183c547865STejun Heo static inline struct blkcg *blkcg_parent(struct blkcg *blkcg)
2193c547865STejun Heo {
2205c9d535bSTejun Heo 	return css_to_blkcg(blkcg->css.parent);
2213c547865STejun Heo }
2223c547865STejun Heo 
2233c547865STejun Heo /**
2240381411eSTejun Heo  * blkg_to_pdata - get policy private data
2250381411eSTejun Heo  * @blkg: blkg of interest
2260381411eSTejun Heo  * @pol: policy of interest
2270381411eSTejun Heo  *
2280381411eSTejun Heo  * Return pointer to private data associated with the @blkg-@pol pair.
2290381411eSTejun Heo  */
230f95a04afSTejun Heo static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg,
2313c798398STejun Heo 						  struct blkcg_policy *pol)
2320381411eSTejun Heo {
233f95a04afSTejun Heo 	return blkg ? blkg->pd[pol->plid] : NULL;
2340381411eSTejun Heo }
2350381411eSTejun Heo 
236*e48453c3SArianna Avanzini static inline struct blkcg_policy_data *blkcg_to_cpd(struct blkcg *blkcg,
237*e48453c3SArianna Avanzini 						     struct blkcg_policy *pol)
238*e48453c3SArianna Avanzini {
239*e48453c3SArianna Avanzini 	return blkcg ? blkcg->pd[pol->plid] : NULL;
240*e48453c3SArianna Avanzini }
241*e48453c3SArianna Avanzini 
2420381411eSTejun Heo /**
2430381411eSTejun Heo  * pdata_to_blkg - get blkg associated with policy private data
244f95a04afSTejun Heo  * @pd: policy private data of interest
2450381411eSTejun Heo  *
246f95a04afSTejun Heo  * @pd is policy private data.  Determine the blkg it's associated with.
2470381411eSTejun Heo  */
248f95a04afSTejun Heo static inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd)
2490381411eSTejun Heo {
250f95a04afSTejun Heo 	return pd ? pd->blkg : NULL;
2510381411eSTejun Heo }
2520381411eSTejun Heo 
25354e7ed12STejun Heo /**
25454e7ed12STejun Heo  * blkg_path - format cgroup path of blkg
25554e7ed12STejun Heo  * @blkg: blkg of interest
25654e7ed12STejun Heo  * @buf: target buffer
25754e7ed12STejun Heo  * @buflen: target buffer length
25854e7ed12STejun Heo  *
25954e7ed12STejun Heo  * Format the path of the cgroup of @blkg into @buf.
26054e7ed12STejun Heo  */
2613c798398STejun Heo static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen)
262afc24d49SVivek Goyal {
263e61734c5STejun Heo 	char *p;
26454e7ed12STejun Heo 
265e61734c5STejun Heo 	p = cgroup_path(blkg->blkcg->css.cgroup, buf, buflen);
266e61734c5STejun Heo 	if (!p) {
26754e7ed12STejun Heo 		strncpy(buf, "<unavailable>", buflen);
268e61734c5STejun Heo 		return -ENAMETOOLONG;
269e61734c5STejun Heo 	}
270e61734c5STejun Heo 
271e61734c5STejun Heo 	memmove(buf, p, buf + buflen - p);
272e61734c5STejun Heo 	return 0;
273afc24d49SVivek Goyal }
274afc24d49SVivek Goyal 
2751adaf3ddSTejun Heo /**
2761adaf3ddSTejun Heo  * blkg_get - get a blkg reference
2771adaf3ddSTejun Heo  * @blkg: blkg to get
2781adaf3ddSTejun Heo  *
279a5049a8aSTejun Heo  * The caller should be holding an existing reference.
2801adaf3ddSTejun Heo  */
2813c798398STejun Heo static inline void blkg_get(struct blkcg_gq *blkg)
2821adaf3ddSTejun Heo {
283a5049a8aSTejun Heo 	WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0);
284a5049a8aSTejun Heo 	atomic_inc(&blkg->refcnt);
2851adaf3ddSTejun Heo }
2861adaf3ddSTejun Heo 
2872a4fd070STejun Heo void __blkg_release_rcu(struct rcu_head *rcu);
2881adaf3ddSTejun Heo 
2891adaf3ddSTejun Heo /**
2901adaf3ddSTejun Heo  * blkg_put - put a blkg reference
2911adaf3ddSTejun Heo  * @blkg: blkg to put
2921adaf3ddSTejun Heo  */
2933c798398STejun Heo static inline void blkg_put(struct blkcg_gq *blkg)
2941adaf3ddSTejun Heo {
295a5049a8aSTejun Heo 	WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0);
296a5049a8aSTejun Heo 	if (atomic_dec_and_test(&blkg->refcnt))
2972a4fd070STejun Heo 		call_rcu(&blkg->rcu_head, __blkg_release_rcu);
2981adaf3ddSTejun Heo }
2991adaf3ddSTejun Heo 
300dd4a4ffcSTejun Heo struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg, struct request_queue *q,
301dd4a4ffcSTejun Heo 			       bool update_hint);
302dd4a4ffcSTejun Heo 
303dd4a4ffcSTejun Heo /**
304dd4a4ffcSTejun Heo  * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants
305dd4a4ffcSTejun Heo  * @d_blkg: loop cursor pointing to the current descendant
306492eb21bSTejun Heo  * @pos_css: used for iteration
307dd4a4ffcSTejun Heo  * @p_blkg: target blkg to walk descendants of
308dd4a4ffcSTejun Heo  *
309dd4a4ffcSTejun Heo  * Walk @c_blkg through the descendants of @p_blkg.  Must be used with RCU
310dd4a4ffcSTejun Heo  * read locked.  If called under either blkcg or queue lock, the iteration
311dd4a4ffcSTejun Heo  * is guaranteed to include all and only online blkgs.  The caller may
312492eb21bSTejun Heo  * update @pos_css by calling css_rightmost_descendant() to skip subtree.
313bd8815a6STejun Heo  * @p_blkg is included in the iteration and the first node to be visited.
314dd4a4ffcSTejun Heo  */
315492eb21bSTejun Heo #define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg)		\
316492eb21bSTejun Heo 	css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css)	\
317492eb21bSTejun Heo 		if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css),	\
318dd4a4ffcSTejun Heo 					      (p_blkg)->q, false)))
319dd4a4ffcSTejun Heo 
320edcb0722STejun Heo /**
321aa539cb3STejun Heo  * blkg_for_each_descendant_post - post-order walk of a blkg's descendants
322aa539cb3STejun Heo  * @d_blkg: loop cursor pointing to the current descendant
323492eb21bSTejun Heo  * @pos_css: used for iteration
324aa539cb3STejun Heo  * @p_blkg: target blkg to walk descendants of
325aa539cb3STejun Heo  *
326aa539cb3STejun Heo  * Similar to blkg_for_each_descendant_pre() but performs post-order
327bd8815a6STejun Heo  * traversal instead.  Synchronization rules are the same.  @p_blkg is
328bd8815a6STejun Heo  * included in the iteration and the last node to be visited.
329aa539cb3STejun Heo  */
330492eb21bSTejun Heo #define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg)		\
331492eb21bSTejun Heo 	css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css)	\
332492eb21bSTejun Heo 		if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css),	\
333aa539cb3STejun Heo 					      (p_blkg)->q, false)))
334aa539cb3STejun Heo 
335aa539cb3STejun Heo /**
336a051661cSTejun Heo  * blk_get_rl - get request_list to use
337a051661cSTejun Heo  * @q: request_queue of interest
338a051661cSTejun Heo  * @bio: bio which will be attached to the allocated request (may be %NULL)
339a051661cSTejun Heo  *
340a051661cSTejun Heo  * The caller wants to allocate a request from @q to use for @bio.  Find
341a051661cSTejun Heo  * the request_list to use and obtain a reference on it.  Should be called
342a051661cSTejun Heo  * under queue_lock.  This function is guaranteed to return non-%NULL
343a051661cSTejun Heo  * request_list.
344a051661cSTejun Heo  */
345a051661cSTejun Heo static inline struct request_list *blk_get_rl(struct request_queue *q,
346a051661cSTejun Heo 					      struct bio *bio)
347a051661cSTejun Heo {
348a051661cSTejun Heo 	struct blkcg *blkcg;
349a051661cSTejun Heo 	struct blkcg_gq *blkg;
350a051661cSTejun Heo 
351a051661cSTejun Heo 	rcu_read_lock();
352a051661cSTejun Heo 
353a051661cSTejun Heo 	blkcg = bio_blkcg(bio);
354a051661cSTejun Heo 
355a051661cSTejun Heo 	/* bypass blkg lookup and use @q->root_rl directly for root */
356a051661cSTejun Heo 	if (blkcg == &blkcg_root)
357a051661cSTejun Heo 		goto root_rl;
358a051661cSTejun Heo 
359a051661cSTejun Heo 	/*
360a051661cSTejun Heo 	 * Try to use blkg->rl.  blkg lookup may fail under memory pressure
361a051661cSTejun Heo 	 * or if either the blkcg or queue is going away.  Fall back to
362a051661cSTejun Heo 	 * root_rl in such cases.
363a051661cSTejun Heo 	 */
364a051661cSTejun Heo 	blkg = blkg_lookup_create(blkcg, q);
365a051661cSTejun Heo 	if (unlikely(IS_ERR(blkg)))
366a051661cSTejun Heo 		goto root_rl;
367a051661cSTejun Heo 
368a051661cSTejun Heo 	blkg_get(blkg);
369a051661cSTejun Heo 	rcu_read_unlock();
370a051661cSTejun Heo 	return &blkg->rl;
371a051661cSTejun Heo root_rl:
372a051661cSTejun Heo 	rcu_read_unlock();
373a051661cSTejun Heo 	return &q->root_rl;
374a051661cSTejun Heo }
375a051661cSTejun Heo 
376a051661cSTejun Heo /**
377a051661cSTejun Heo  * blk_put_rl - put request_list
378a051661cSTejun Heo  * @rl: request_list to put
379a051661cSTejun Heo  *
380a051661cSTejun Heo  * Put the reference acquired by blk_get_rl().  Should be called under
381a051661cSTejun Heo  * queue_lock.
382a051661cSTejun Heo  */
383a051661cSTejun Heo static inline void blk_put_rl(struct request_list *rl)
384a051661cSTejun Heo {
385a051661cSTejun Heo 	/* root_rl may not have blkg set */
386a051661cSTejun Heo 	if (rl->blkg && rl->blkg->blkcg != &blkcg_root)
387a051661cSTejun Heo 		blkg_put(rl->blkg);
388a051661cSTejun Heo }
389a051661cSTejun Heo 
390a051661cSTejun Heo /**
391a051661cSTejun Heo  * blk_rq_set_rl - associate a request with a request_list
392a051661cSTejun Heo  * @rq: request of interest
393a051661cSTejun Heo  * @rl: target request_list
394a051661cSTejun Heo  *
395a051661cSTejun Heo  * Associate @rq with @rl so that accounting and freeing can know the
396a051661cSTejun Heo  * request_list @rq came from.
397a051661cSTejun Heo  */
398a051661cSTejun Heo static inline void blk_rq_set_rl(struct request *rq, struct request_list *rl)
399a051661cSTejun Heo {
400a051661cSTejun Heo 	rq->rl = rl;
401a051661cSTejun Heo }
402a051661cSTejun Heo 
403a051661cSTejun Heo /**
404a051661cSTejun Heo  * blk_rq_rl - return the request_list a request came from
405a051661cSTejun Heo  * @rq: request of interest
406a051661cSTejun Heo  *
407a051661cSTejun Heo  * Return the request_list @rq is allocated from.
408a051661cSTejun Heo  */
409a051661cSTejun Heo static inline struct request_list *blk_rq_rl(struct request *rq)
410a051661cSTejun Heo {
411a051661cSTejun Heo 	return rq->rl;
412a051661cSTejun Heo }
413a051661cSTejun Heo 
414a051661cSTejun Heo struct request_list *__blk_queue_next_rl(struct request_list *rl,
415a051661cSTejun Heo 					 struct request_queue *q);
416a051661cSTejun Heo /**
417a051661cSTejun Heo  * blk_queue_for_each_rl - iterate through all request_lists of a request_queue
418a051661cSTejun Heo  *
419a051661cSTejun Heo  * Should be used under queue_lock.
420a051661cSTejun Heo  */
421a051661cSTejun Heo #define blk_queue_for_each_rl(rl, q)	\
422a051661cSTejun Heo 	for ((rl) = &(q)->root_rl; (rl); (rl) = __blk_queue_next_rl((rl), (q)))
423a051661cSTejun Heo 
42490d3839bSPeter Zijlstra static inline void blkg_stat_init(struct blkg_stat *stat)
42590d3839bSPeter Zijlstra {
42690d3839bSPeter Zijlstra 	u64_stats_init(&stat->syncp);
42790d3839bSPeter Zijlstra }
42890d3839bSPeter Zijlstra 
429a051661cSTejun Heo /**
430edcb0722STejun Heo  * blkg_stat_add - add a value to a blkg_stat
431edcb0722STejun Heo  * @stat: target blkg_stat
432edcb0722STejun Heo  * @val: value to add
433edcb0722STejun Heo  *
434edcb0722STejun Heo  * Add @val to @stat.  The caller is responsible for synchronizing calls to
435edcb0722STejun Heo  * this function.
436edcb0722STejun Heo  */
437edcb0722STejun Heo static inline void blkg_stat_add(struct blkg_stat *stat, uint64_t val)
438edcb0722STejun Heo {
439edcb0722STejun Heo 	u64_stats_update_begin(&stat->syncp);
440edcb0722STejun Heo 	stat->cnt += val;
441edcb0722STejun Heo 	u64_stats_update_end(&stat->syncp);
442edcb0722STejun Heo }
443edcb0722STejun Heo 
444edcb0722STejun Heo /**
445edcb0722STejun Heo  * blkg_stat_read - read the current value of a blkg_stat
446edcb0722STejun Heo  * @stat: blkg_stat to read
447edcb0722STejun Heo  *
448edcb0722STejun Heo  * Read the current value of @stat.  This function can be called without
449edcb0722STejun Heo  * synchroniztion and takes care of u64 atomicity.
450edcb0722STejun Heo  */
451edcb0722STejun Heo static inline uint64_t blkg_stat_read(struct blkg_stat *stat)
452edcb0722STejun Heo {
453edcb0722STejun Heo 	unsigned int start;
454edcb0722STejun Heo 	uint64_t v;
455edcb0722STejun Heo 
456edcb0722STejun Heo 	do {
45757a7744eSEric W. Biederman 		start = u64_stats_fetch_begin_irq(&stat->syncp);
458edcb0722STejun Heo 		v = stat->cnt;
45957a7744eSEric W. Biederman 	} while (u64_stats_fetch_retry_irq(&stat->syncp, start));
460edcb0722STejun Heo 
461edcb0722STejun Heo 	return v;
462edcb0722STejun Heo }
463edcb0722STejun Heo 
464edcb0722STejun Heo /**
465edcb0722STejun Heo  * blkg_stat_reset - reset a blkg_stat
466edcb0722STejun Heo  * @stat: blkg_stat to reset
467edcb0722STejun Heo  */
468edcb0722STejun Heo static inline void blkg_stat_reset(struct blkg_stat *stat)
469edcb0722STejun Heo {
470edcb0722STejun Heo 	stat->cnt = 0;
471edcb0722STejun Heo }
472edcb0722STejun Heo 
473edcb0722STejun Heo /**
47416b3de66STejun Heo  * blkg_stat_merge - merge a blkg_stat into another
47516b3de66STejun Heo  * @to: the destination blkg_stat
47616b3de66STejun Heo  * @from: the source
47716b3de66STejun Heo  *
47816b3de66STejun Heo  * Add @from's count to @to.
47916b3de66STejun Heo  */
48016b3de66STejun Heo static inline void blkg_stat_merge(struct blkg_stat *to, struct blkg_stat *from)
48116b3de66STejun Heo {
48216b3de66STejun Heo 	blkg_stat_add(to, blkg_stat_read(from));
48316b3de66STejun Heo }
48416b3de66STejun Heo 
48590d3839bSPeter Zijlstra static inline void blkg_rwstat_init(struct blkg_rwstat *rwstat)
48690d3839bSPeter Zijlstra {
48790d3839bSPeter Zijlstra 	u64_stats_init(&rwstat->syncp);
48890d3839bSPeter Zijlstra }
48990d3839bSPeter Zijlstra 
49016b3de66STejun Heo /**
491edcb0722STejun Heo  * blkg_rwstat_add - add a value to a blkg_rwstat
492edcb0722STejun Heo  * @rwstat: target blkg_rwstat
493edcb0722STejun Heo  * @rw: mask of REQ_{WRITE|SYNC}
494edcb0722STejun Heo  * @val: value to add
495edcb0722STejun Heo  *
496edcb0722STejun Heo  * Add @val to @rwstat.  The counters are chosen according to @rw.  The
497edcb0722STejun Heo  * caller is responsible for synchronizing calls to this function.
498edcb0722STejun Heo  */
499edcb0722STejun Heo static inline void blkg_rwstat_add(struct blkg_rwstat *rwstat,
500edcb0722STejun Heo 				   int rw, uint64_t val)
501edcb0722STejun Heo {
502edcb0722STejun Heo 	u64_stats_update_begin(&rwstat->syncp);
503edcb0722STejun Heo 
504edcb0722STejun Heo 	if (rw & REQ_WRITE)
505edcb0722STejun Heo 		rwstat->cnt[BLKG_RWSTAT_WRITE] += val;
506edcb0722STejun Heo 	else
507edcb0722STejun Heo 		rwstat->cnt[BLKG_RWSTAT_READ] += val;
508edcb0722STejun Heo 	if (rw & REQ_SYNC)
509edcb0722STejun Heo 		rwstat->cnt[BLKG_RWSTAT_SYNC] += val;
510edcb0722STejun Heo 	else
511edcb0722STejun Heo 		rwstat->cnt[BLKG_RWSTAT_ASYNC] += val;
512edcb0722STejun Heo 
513edcb0722STejun Heo 	u64_stats_update_end(&rwstat->syncp);
514edcb0722STejun Heo }
515edcb0722STejun Heo 
516edcb0722STejun Heo /**
517edcb0722STejun Heo  * blkg_rwstat_read - read the current values of a blkg_rwstat
518edcb0722STejun Heo  * @rwstat: blkg_rwstat to read
519edcb0722STejun Heo  *
520edcb0722STejun Heo  * Read the current snapshot of @rwstat and return it as the return value.
521edcb0722STejun Heo  * This function can be called without synchronization and takes care of
522edcb0722STejun Heo  * u64 atomicity.
523edcb0722STejun Heo  */
524c94bed89STejun Heo static inline struct blkg_rwstat blkg_rwstat_read(struct blkg_rwstat *rwstat)
525edcb0722STejun Heo {
526edcb0722STejun Heo 	unsigned int start;
527edcb0722STejun Heo 	struct blkg_rwstat tmp;
528edcb0722STejun Heo 
529edcb0722STejun Heo 	do {
53057a7744eSEric W. Biederman 		start = u64_stats_fetch_begin_irq(&rwstat->syncp);
531edcb0722STejun Heo 		tmp = *rwstat;
53257a7744eSEric W. Biederman 	} while (u64_stats_fetch_retry_irq(&rwstat->syncp, start));
533edcb0722STejun Heo 
534edcb0722STejun Heo 	return tmp;
535edcb0722STejun Heo }
536edcb0722STejun Heo 
537edcb0722STejun Heo /**
5384d5e80a7STejun Heo  * blkg_rwstat_total - read the total count of a blkg_rwstat
539edcb0722STejun Heo  * @rwstat: blkg_rwstat to read
540edcb0722STejun Heo  *
541edcb0722STejun Heo  * Return the total count of @rwstat regardless of the IO direction.  This
542edcb0722STejun Heo  * function can be called without synchronization and takes care of u64
543edcb0722STejun Heo  * atomicity.
544edcb0722STejun Heo  */
5454d5e80a7STejun Heo static inline uint64_t blkg_rwstat_total(struct blkg_rwstat *rwstat)
546edcb0722STejun Heo {
547edcb0722STejun Heo 	struct blkg_rwstat tmp = blkg_rwstat_read(rwstat);
548edcb0722STejun Heo 
549edcb0722STejun Heo 	return tmp.cnt[BLKG_RWSTAT_READ] + tmp.cnt[BLKG_RWSTAT_WRITE];
550edcb0722STejun Heo }
551edcb0722STejun Heo 
552edcb0722STejun Heo /**
553edcb0722STejun Heo  * blkg_rwstat_reset - reset a blkg_rwstat
554edcb0722STejun Heo  * @rwstat: blkg_rwstat to reset
555edcb0722STejun Heo  */
556edcb0722STejun Heo static inline void blkg_rwstat_reset(struct blkg_rwstat *rwstat)
557edcb0722STejun Heo {
558edcb0722STejun Heo 	memset(rwstat->cnt, 0, sizeof(rwstat->cnt));
559edcb0722STejun Heo }
560edcb0722STejun Heo 
56116b3de66STejun Heo /**
56216b3de66STejun Heo  * blkg_rwstat_merge - merge a blkg_rwstat into another
56316b3de66STejun Heo  * @to: the destination blkg_rwstat
56416b3de66STejun Heo  * @from: the source
56516b3de66STejun Heo  *
56616b3de66STejun Heo  * Add @from's counts to @to.
56716b3de66STejun Heo  */
56816b3de66STejun Heo static inline void blkg_rwstat_merge(struct blkg_rwstat *to,
56916b3de66STejun Heo 				     struct blkg_rwstat *from)
57016b3de66STejun Heo {
57116b3de66STejun Heo 	struct blkg_rwstat v = blkg_rwstat_read(from);
57216b3de66STejun Heo 	int i;
57316b3de66STejun Heo 
57416b3de66STejun Heo 	u64_stats_update_begin(&to->syncp);
57516b3de66STejun Heo 	for (i = 0; i < BLKG_RWSTAT_NR; i++)
57616b3de66STejun Heo 		to->cnt[i] += v.cnt[i];
57716b3de66STejun Heo 	u64_stats_update_end(&to->syncp);
57816b3de66STejun Heo }
57916b3de66STejun Heo 
58036558c8aSTejun Heo #else	/* CONFIG_BLK_CGROUP */
58136558c8aSTejun Heo 
58236558c8aSTejun Heo struct cgroup;
583b1208b56STejun Heo struct blkcg;
5842f5ea477SJens Axboe 
585f95a04afSTejun Heo struct blkg_policy_data {
586f95a04afSTejun Heo };
587f95a04afSTejun Heo 
588*e48453c3SArianna Avanzini struct blkcg_policy_data {
589*e48453c3SArianna Avanzini };
590*e48453c3SArianna Avanzini 
5913c798398STejun Heo struct blkcg_gq {
5922f5ea477SJens Axboe };
5932f5ea477SJens Axboe 
5943c798398STejun Heo struct blkcg_policy {
5953e252066SVivek Goyal };
5963e252066SVivek Goyal 
5973c798398STejun Heo static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
5985efd6113STejun Heo static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
5995efd6113STejun Heo static inline void blkcg_drain_queue(struct request_queue *q) { }
6005efd6113STejun Heo static inline void blkcg_exit_queue(struct request_queue *q) { }
601d5bf0291SJens Axboe static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
6023c798398STejun Heo static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { }
603a2b1693bSTejun Heo static inline int blkcg_activate_policy(struct request_queue *q,
6043c798398STejun Heo 					const struct blkcg_policy *pol) { return 0; }
605a2b1693bSTejun Heo static inline void blkcg_deactivate_policy(struct request_queue *q,
6063c798398STejun Heo 					   const struct blkcg_policy *pol) { }
6073e252066SVivek Goyal 
608b1208b56STejun Heo static inline struct blkcg *bio_blkcg(struct bio *bio) { return NULL; }
609a051661cSTejun Heo 
610f95a04afSTejun Heo static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg,
6113c798398STejun Heo 						  struct blkcg_policy *pol) { return NULL; }
612f95a04afSTejun Heo static inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd) { return NULL; }
6133c798398STejun Heo static inline char *blkg_path(struct blkcg_gq *blkg) { return NULL; }
6143c798398STejun Heo static inline void blkg_get(struct blkcg_gq *blkg) { }
6153c798398STejun Heo static inline void blkg_put(struct blkcg_gq *blkg) { }
616afc24d49SVivek Goyal 
617a051661cSTejun Heo static inline struct request_list *blk_get_rl(struct request_queue *q,
618a051661cSTejun Heo 					      struct bio *bio) { return &q->root_rl; }
619a051661cSTejun Heo static inline void blk_put_rl(struct request_list *rl) { }
620a051661cSTejun Heo static inline void blk_rq_set_rl(struct request *rq, struct request_list *rl) { }
621a051661cSTejun Heo static inline struct request_list *blk_rq_rl(struct request *rq) { return &rq->q->root_rl; }
622a051661cSTejun Heo 
623a051661cSTejun Heo #define blk_queue_for_each_rl(rl, q)	\
624a051661cSTejun Heo 	for ((rl) = &(q)->root_rl; (rl); (rl) = NULL)
625a051661cSTejun Heo 
62636558c8aSTejun Heo #endif	/* CONFIG_BLK_CGROUP */
62731e4c28dSVivek Goyal #endif	/* _BLK_CGROUP_H */
628