xref: /linux/block/blk-cgroup.h (revision e8989fae38d9831c72b20375a206a919ca468c52)
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>
1831e4c28dSVivek Goyal 
19062a644dSVivek Goyal enum blkio_policy_id {
20062a644dSVivek Goyal 	BLKIO_POLICY_PROP = 0,		/* Proportional Bandwidth division */
214c9eefa1SVivek Goyal 	BLKIO_POLICY_THROTL,		/* Throttling */
22035d10b2STejun Heo 
23035d10b2STejun Heo 	BLKIO_NR_POLICIES,
24062a644dSVivek Goyal };
25062a644dSVivek Goyal 
269355aedeSVivek Goyal /* Max limits for throttle policy */
279355aedeSVivek Goyal #define THROTL_IOPS_MAX		UINT_MAX
289355aedeSVivek Goyal 
2932e380aeSTejun Heo #ifdef CONFIG_BLK_CGROUP
302f5ea477SJens Axboe 
3184c124daSDivyesh Shah enum stat_type {
3284c124daSDivyesh Shah 	/* Total time spent (in ns) between request dispatch to the driver and
3384c124daSDivyesh Shah 	 * request completion for IOs doen by this cgroup. This may not be
3484c124daSDivyesh Shah 	 * accurate when NCQ is turned on. */
3584c124daSDivyesh Shah 	BLKIO_STAT_SERVICE_TIME = 0,
3684c124daSDivyesh Shah 	/* Total time spent waiting in scheduler queue in ns */
3784c124daSDivyesh Shah 	BLKIO_STAT_WAIT_TIME,
38cdc1184cSDivyesh Shah 	/* Number of IOs queued up */
39cdc1184cSDivyesh Shah 	BLKIO_STAT_QUEUED,
4084c124daSDivyesh Shah 	/* All the single valued stats go below this */
4184c124daSDivyesh Shah 	BLKIO_STAT_TIME,
42a23e6869SVivek Goyal #ifdef CONFIG_DEBUG_BLK_CGROUP
43167400d3SJustin TerAvest 	/* Time not charged to this cgroup */
44167400d3SJustin TerAvest 	BLKIO_STAT_UNACCOUNTED_TIME,
45cdc1184cSDivyesh Shah 	BLKIO_STAT_AVG_QUEUE_SIZE,
46812df48dSDivyesh Shah 	BLKIO_STAT_IDLE_TIME,
47812df48dSDivyesh Shah 	BLKIO_STAT_EMPTY_TIME,
48812df48dSDivyesh Shah 	BLKIO_STAT_GROUP_WAIT_TIME,
4984c124daSDivyesh Shah 	BLKIO_STAT_DEQUEUE
5084c124daSDivyesh Shah #endif
5184c124daSDivyesh Shah };
5284c124daSDivyesh Shah 
535624a4e4SVivek Goyal /* Per cpu stats */
545624a4e4SVivek Goyal enum stat_type_cpu {
555624a4e4SVivek Goyal 	BLKIO_STAT_CPU_SECTORS,
565624a4e4SVivek Goyal 	/* Total bytes transferred */
575624a4e4SVivek Goyal 	BLKIO_STAT_CPU_SERVICE_BYTES,
585624a4e4SVivek Goyal 	/* Total IOs serviced, post merge */
595624a4e4SVivek Goyal 	BLKIO_STAT_CPU_SERVICED,
60317389a7SVivek Goyal 	/* Number of IOs merged */
61317389a7SVivek Goyal 	BLKIO_STAT_CPU_MERGED,
625624a4e4SVivek Goyal 	BLKIO_STAT_CPU_NR
635624a4e4SVivek Goyal };
645624a4e4SVivek Goyal 
6584c124daSDivyesh Shah enum stat_sub_type {
6684c124daSDivyesh Shah 	BLKIO_STAT_READ = 0,
6784c124daSDivyesh Shah 	BLKIO_STAT_WRITE,
6884c124daSDivyesh Shah 	BLKIO_STAT_SYNC,
6984c124daSDivyesh Shah 	BLKIO_STAT_ASYNC,
7084c124daSDivyesh Shah 	BLKIO_STAT_TOTAL
71303a3acbSDivyesh Shah };
72303a3acbSDivyesh Shah 
73812df48dSDivyesh Shah /* blkg state flags */
74812df48dSDivyesh Shah enum blkg_state_flags {
75812df48dSDivyesh Shah 	BLKG_waiting = 0,
76812df48dSDivyesh Shah 	BLKG_idling,
77812df48dSDivyesh Shah 	BLKG_empty,
78812df48dSDivyesh Shah };
79812df48dSDivyesh Shah 
80062a644dSVivek Goyal /* cgroup files owned by proportional weight policy */
81062a644dSVivek Goyal enum blkcg_file_name_prop {
82062a644dSVivek Goyal 	BLKIO_PROP_weight = 1,
83062a644dSVivek Goyal 	BLKIO_PROP_weight_device,
84062a644dSVivek Goyal 	BLKIO_PROP_io_service_bytes,
85062a644dSVivek Goyal 	BLKIO_PROP_io_serviced,
86062a644dSVivek Goyal 	BLKIO_PROP_time,
87062a644dSVivek Goyal 	BLKIO_PROP_sectors,
88167400d3SJustin TerAvest 	BLKIO_PROP_unaccounted_time,
89062a644dSVivek Goyal 	BLKIO_PROP_io_service_time,
90062a644dSVivek Goyal 	BLKIO_PROP_io_wait_time,
91062a644dSVivek Goyal 	BLKIO_PROP_io_merged,
92062a644dSVivek Goyal 	BLKIO_PROP_io_queued,
93062a644dSVivek Goyal 	BLKIO_PROP_avg_queue_size,
94062a644dSVivek Goyal 	BLKIO_PROP_group_wait_time,
95062a644dSVivek Goyal 	BLKIO_PROP_idle_time,
96062a644dSVivek Goyal 	BLKIO_PROP_empty_time,
97062a644dSVivek Goyal 	BLKIO_PROP_dequeue,
98062a644dSVivek Goyal };
99062a644dSVivek Goyal 
1004c9eefa1SVivek Goyal /* cgroup files owned by throttle policy */
1014c9eefa1SVivek Goyal enum blkcg_file_name_throtl {
1024c9eefa1SVivek Goyal 	BLKIO_THROTL_read_bps_device,
1034c9eefa1SVivek Goyal 	BLKIO_THROTL_write_bps_device,
1047702e8f4SVivek Goyal 	BLKIO_THROTL_read_iops_device,
1057702e8f4SVivek Goyal 	BLKIO_THROTL_write_iops_device,
1064c9eefa1SVivek Goyal 	BLKIO_THROTL_io_service_bytes,
1074c9eefa1SVivek Goyal 	BLKIO_THROTL_io_serviced,
1084c9eefa1SVivek Goyal };
1094c9eefa1SVivek Goyal 
11031e4c28dSVivek Goyal struct blkio_cgroup {
11131e4c28dSVivek Goyal 	struct cgroup_subsys_state css;
11231e4c28dSVivek Goyal 	unsigned int weight;
11331e4c28dSVivek Goyal 	spinlock_t lock;
11431e4c28dSVivek Goyal 	struct hlist_head blkg_list;
11531e4c28dSVivek Goyal };
11631e4c28dSVivek Goyal 
117303a3acbSDivyesh Shah struct blkio_group_stats {
118303a3acbSDivyesh Shah 	/* total disk time and nr sectors dispatched by this group */
119303a3acbSDivyesh Shah 	uint64_t time;
120cdc1184cSDivyesh Shah 	uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL];
121303a3acbSDivyesh Shah #ifdef CONFIG_DEBUG_BLK_CGROUP
122a23e6869SVivek Goyal 	/* Time not charged to this cgroup */
123a23e6869SVivek Goyal 	uint64_t unaccounted_time;
124a23e6869SVivek Goyal 
125cdc1184cSDivyesh Shah 	/* Sum of number of IOs queued across all samples */
126cdc1184cSDivyesh Shah 	uint64_t avg_queue_size_sum;
127cdc1184cSDivyesh Shah 	/* Count of samples taken for average */
128cdc1184cSDivyesh Shah 	uint64_t avg_queue_size_samples;
129303a3acbSDivyesh Shah 	/* How many times this group has been removed from service tree */
130303a3acbSDivyesh Shah 	unsigned long dequeue;
131812df48dSDivyesh Shah 
132812df48dSDivyesh Shah 	/* Total time spent waiting for it to be assigned a timeslice. */
133812df48dSDivyesh Shah 	uint64_t group_wait_time;
134812df48dSDivyesh Shah 	uint64_t start_group_wait_time;
135812df48dSDivyesh Shah 
136812df48dSDivyesh Shah 	/* Time spent idling for this blkio_group */
137812df48dSDivyesh Shah 	uint64_t idle_time;
138812df48dSDivyesh Shah 	uint64_t start_idle_time;
139812df48dSDivyesh Shah 	/*
140812df48dSDivyesh Shah 	 * Total time when we have requests queued and do not contain the
141812df48dSDivyesh Shah 	 * current active queue.
142812df48dSDivyesh Shah 	 */
143812df48dSDivyesh Shah 	uint64_t empty_time;
144812df48dSDivyesh Shah 	uint64_t start_empty_time;
145812df48dSDivyesh Shah 	uint16_t flags;
146303a3acbSDivyesh Shah #endif
147303a3acbSDivyesh Shah };
148303a3acbSDivyesh Shah 
1495624a4e4SVivek Goyal /* Per cpu blkio group stats */
1505624a4e4SVivek Goyal struct blkio_group_stats_cpu {
1515624a4e4SVivek Goyal 	uint64_t sectors;
1525624a4e4SVivek Goyal 	uint64_t stat_arr_cpu[BLKIO_STAT_CPU_NR][BLKIO_STAT_TOTAL];
153575969a0SVivek Goyal 	struct u64_stats_sync syncp;
1545624a4e4SVivek Goyal };
1555624a4e4SVivek Goyal 
156e56da7e2STejun Heo struct blkio_group_conf {
157e56da7e2STejun Heo 	unsigned int weight;
158e56da7e2STejun Heo 	unsigned int iops[2];
159e56da7e2STejun Heo 	u64 bps[2];
160e56da7e2STejun Heo };
161e56da7e2STejun Heo 
1620381411eSTejun Heo /* per-blkg per-policy data */
1630381411eSTejun Heo struct blkg_policy_data {
1640381411eSTejun Heo 	/* the blkg this per-policy data belongs to */
1650381411eSTejun Heo 	struct blkio_group *blkg;
1660381411eSTejun Heo 
167549d3aa8STejun Heo 	/* Configuration */
168549d3aa8STejun Heo 	struct blkio_group_conf conf;
169549d3aa8STejun Heo 
170549d3aa8STejun Heo 	struct blkio_group_stats stats;
171549d3aa8STejun Heo 	/* Per cpu stats pointer */
172549d3aa8STejun Heo 	struct blkio_group_stats_cpu __percpu *stats_cpu;
173549d3aa8STejun Heo 
1740381411eSTejun Heo 	/* pol->pdata_size bytes of private data used by policy impl */
1750381411eSTejun Heo 	char pdata[] __aligned(__alignof__(unsigned long long));
1760381411eSTejun Heo };
1770381411eSTejun Heo 
17831e4c28dSVivek Goyal struct blkio_group {
179ca32aefcSTejun Heo 	/* Pointer to the associated request_queue, RCU protected */
180ca32aefcSTejun Heo 	struct request_queue __rcu *q;
181*e8989faeSTejun Heo 	struct list_head q_node;
18231e4c28dSVivek Goyal 	struct hlist_node blkcg_node;
1837ee9c562STejun Heo 	struct blkio_cgroup *blkcg;
1842868ef7bSVivek Goyal 	/* Store cgroup path */
1852868ef7bSVivek Goyal 	char path[128];
1861adaf3ddSTejun Heo 	/* reference count */
1871adaf3ddSTejun Heo 	int refcnt;
18822084190SVivek Goyal 
189303a3acbSDivyesh Shah 	/* Need to serialize the stats in the case of reset/update */
190303a3acbSDivyesh Shah 	spinlock_t stats_lock;
191549d3aa8STejun Heo 	struct blkg_policy_data *pd[BLKIO_NR_POLICIES];
1921adaf3ddSTejun Heo 
1931adaf3ddSTejun Heo 	struct rcu_head rcu_head;
19431e4c28dSVivek Goyal };
19531e4c28dSVivek Goyal 
1960381411eSTejun Heo typedef void (blkio_init_group_fn)(struct blkio_group *blkg);
197ca32aefcSTejun Heo typedef void (blkio_update_group_weight_fn)(struct request_queue *q,
198fe071437SVivek Goyal 			struct blkio_group *blkg, unsigned int weight);
199ca32aefcSTejun Heo typedef void (blkio_update_group_read_bps_fn)(struct request_queue *q,
200fe071437SVivek Goyal 			struct blkio_group *blkg, u64 read_bps);
201ca32aefcSTejun Heo typedef void (blkio_update_group_write_bps_fn)(struct request_queue *q,
202fe071437SVivek Goyal 			struct blkio_group *blkg, u64 write_bps);
203ca32aefcSTejun Heo typedef void (blkio_update_group_read_iops_fn)(struct request_queue *q,
204fe071437SVivek Goyal 			struct blkio_group *blkg, unsigned int read_iops);
205ca32aefcSTejun Heo typedef void (blkio_update_group_write_iops_fn)(struct request_queue *q,
206fe071437SVivek Goyal 			struct blkio_group *blkg, unsigned int write_iops);
2073e252066SVivek Goyal 
2083e252066SVivek Goyal struct blkio_policy_ops {
2090381411eSTejun Heo 	blkio_init_group_fn *blkio_init_group_fn;
2103e252066SVivek Goyal 	blkio_update_group_weight_fn *blkio_update_group_weight_fn;
2114c9eefa1SVivek Goyal 	blkio_update_group_read_bps_fn *blkio_update_group_read_bps_fn;
2124c9eefa1SVivek Goyal 	blkio_update_group_write_bps_fn *blkio_update_group_write_bps_fn;
2137702e8f4SVivek Goyal 	blkio_update_group_read_iops_fn *blkio_update_group_read_iops_fn;
2147702e8f4SVivek Goyal 	blkio_update_group_write_iops_fn *blkio_update_group_write_iops_fn;
2153e252066SVivek Goyal };
2163e252066SVivek Goyal 
2173e252066SVivek Goyal struct blkio_policy_type {
2183e252066SVivek Goyal 	struct list_head list;
2193e252066SVivek Goyal 	struct blkio_policy_ops ops;
220062a644dSVivek Goyal 	enum blkio_policy_id plid;
2210381411eSTejun Heo 	size_t pdata_size;		/* policy specific private data size */
2223e252066SVivek Goyal };
2233e252066SVivek Goyal 
2245efd6113STejun Heo extern int blkcg_init_queue(struct request_queue *q);
2255efd6113STejun Heo extern void blkcg_drain_queue(struct request_queue *q);
2265efd6113STejun Heo extern void blkcg_exit_queue(struct request_queue *q);
2275efd6113STejun Heo 
2283e252066SVivek Goyal /* Blkio controller policy registration */
2293e252066SVivek Goyal extern void blkio_policy_register(struct blkio_policy_type *);
2303e252066SVivek Goyal extern void blkio_policy_unregister(struct blkio_policy_type *);
231*e8989faeSTejun Heo extern void blkg_destroy_all(struct request_queue *q, bool destroy_root);
232*e8989faeSTejun Heo extern void update_root_blkg_pd(struct request_queue *q,
233*e8989faeSTejun Heo 				enum blkio_policy_id plid);
2343e252066SVivek Goyal 
2350381411eSTejun Heo /**
2360381411eSTejun Heo  * blkg_to_pdata - get policy private data
2370381411eSTejun Heo  * @blkg: blkg of interest
2380381411eSTejun Heo  * @pol: policy of interest
2390381411eSTejun Heo  *
2400381411eSTejun Heo  * Return pointer to private data associated with the @blkg-@pol pair.
2410381411eSTejun Heo  */
2420381411eSTejun Heo static inline void *blkg_to_pdata(struct blkio_group *blkg,
2430381411eSTejun Heo 			      struct blkio_policy_type *pol)
2440381411eSTejun Heo {
245549d3aa8STejun Heo 	return blkg ? blkg->pd[pol->plid]->pdata : NULL;
2460381411eSTejun Heo }
2470381411eSTejun Heo 
2480381411eSTejun Heo /**
2490381411eSTejun Heo  * pdata_to_blkg - get blkg associated with policy private data
2500381411eSTejun Heo  * @pdata: policy private data of interest
2510381411eSTejun Heo  * @pol: policy @pdata is for
2520381411eSTejun Heo  *
2530381411eSTejun Heo  * @pdata is policy private data for @pol.  Determine the blkg it's
2540381411eSTejun Heo  * associated with.
2550381411eSTejun Heo  */
2560381411eSTejun Heo static inline struct blkio_group *pdata_to_blkg(void *pdata,
2570381411eSTejun Heo 						struct blkio_policy_type *pol)
2580381411eSTejun Heo {
2590381411eSTejun Heo 	if (pdata) {
2600381411eSTejun Heo 		struct blkg_policy_data *pd =
2610381411eSTejun Heo 			container_of(pdata, struct blkg_policy_data, pdata);
2620381411eSTejun Heo 		return pd->blkg;
2630381411eSTejun Heo 	}
2640381411eSTejun Heo 	return NULL;
2650381411eSTejun Heo }
2660381411eSTejun Heo 
267afc24d49SVivek Goyal static inline char *blkg_path(struct blkio_group *blkg)
268afc24d49SVivek Goyal {
269afc24d49SVivek Goyal 	return blkg->path;
270afc24d49SVivek Goyal }
271afc24d49SVivek Goyal 
2721adaf3ddSTejun Heo /**
2731adaf3ddSTejun Heo  * blkg_get - get a blkg reference
2741adaf3ddSTejun Heo  * @blkg: blkg to get
2751adaf3ddSTejun Heo  *
2761adaf3ddSTejun Heo  * The caller should be holding queue_lock and an existing reference.
2771adaf3ddSTejun Heo  */
2781adaf3ddSTejun Heo static inline void blkg_get(struct blkio_group *blkg)
2791adaf3ddSTejun Heo {
2801adaf3ddSTejun Heo 	lockdep_assert_held(blkg->q->queue_lock);
2811adaf3ddSTejun Heo 	WARN_ON_ONCE(!blkg->refcnt);
2821adaf3ddSTejun Heo 	blkg->refcnt++;
2831adaf3ddSTejun Heo }
2841adaf3ddSTejun Heo 
2851adaf3ddSTejun Heo void __blkg_release(struct blkio_group *blkg);
2861adaf3ddSTejun Heo 
2871adaf3ddSTejun Heo /**
2881adaf3ddSTejun Heo  * blkg_put - put a blkg reference
2891adaf3ddSTejun Heo  * @blkg: blkg to put
2901adaf3ddSTejun Heo  *
2911adaf3ddSTejun Heo  * The caller should be holding queue_lock.
2921adaf3ddSTejun Heo  */
2931adaf3ddSTejun Heo static inline void blkg_put(struct blkio_group *blkg)
2941adaf3ddSTejun Heo {
2951adaf3ddSTejun Heo 	lockdep_assert_held(blkg->q->queue_lock);
2961adaf3ddSTejun Heo 	WARN_ON_ONCE(blkg->refcnt <= 0);
2971adaf3ddSTejun Heo 	if (!--blkg->refcnt)
2981adaf3ddSTejun Heo 		__blkg_release(blkg);
2991adaf3ddSTejun Heo }
3001adaf3ddSTejun Heo 
3012f5ea477SJens Axboe #else
3022f5ea477SJens Axboe 
3032f5ea477SJens Axboe struct blkio_group {
3042f5ea477SJens Axboe };
3052f5ea477SJens Axboe 
3063e252066SVivek Goyal struct blkio_policy_type {
3073e252066SVivek Goyal };
3083e252066SVivek Goyal 
3095efd6113STejun Heo static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
3105efd6113STejun Heo static inline void blkcg_drain_queue(struct request_queue *q) { }
3115efd6113STejun Heo static inline void blkcg_exit_queue(struct request_queue *q) { }
3123e252066SVivek Goyal static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { }
3133e252066SVivek Goyal static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { }
31403aa264aSTejun Heo static inline void blkg_destroy_all(struct request_queue *q,
31503aa264aSTejun Heo 				    bool destory_root) { }
316*e8989faeSTejun Heo static inline void update_root_blkg_pd(struct request_queue *q,
317*e8989faeSTejun Heo 				       enum blkio_policy_id plid) { }
3183e252066SVivek Goyal 
3190381411eSTejun Heo static inline void *blkg_to_pdata(struct blkio_group *blkg,
3200381411eSTejun Heo 				struct blkio_policy_type *pol) { return NULL; }
3210381411eSTejun Heo static inline struct blkio_group *pdata_to_blkg(void *pdata,
3220381411eSTejun Heo 				struct blkio_policy_type *pol) { return NULL; }
323afc24d49SVivek Goyal static inline char *blkg_path(struct blkio_group *blkg) { return NULL; }
3241adaf3ddSTejun Heo static inline void blkg_get(struct blkio_group *blkg) { }
3251adaf3ddSTejun Heo static inline void blkg_put(struct blkio_group *blkg) { }
326afc24d49SVivek Goyal 
3272f5ea477SJens Axboe #endif
3282f5ea477SJens Axboe 
329df457f84SJustin TerAvest #define BLKIO_WEIGHT_MIN	10
33031e4c28dSVivek Goyal #define BLKIO_WEIGHT_MAX	1000
33131e4c28dSVivek Goyal #define BLKIO_WEIGHT_DEFAULT	500
33231e4c28dSVivek Goyal 
3332868ef7bSVivek Goyal #ifdef CONFIG_DEBUG_BLK_CGROUP
334c1768268STejun Heo void blkiocg_update_avg_queue_size_stats(struct blkio_group *blkg,
335c1768268STejun Heo 					 struct blkio_policy_type *pol);
3369195291eSDivyesh Shah void blkiocg_update_dequeue_stats(struct blkio_group *blkg,
337c1768268STejun Heo 				  struct blkio_policy_type *pol,
33822084190SVivek Goyal 				  unsigned long dequeue);
339c1768268STejun Heo void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg,
340c1768268STejun Heo 					struct blkio_policy_type *pol);
341c1768268STejun Heo void blkiocg_update_idle_time_stats(struct blkio_group *blkg,
342c1768268STejun Heo 				    struct blkio_policy_type *pol);
343c1768268STejun Heo void blkiocg_set_start_empty_time(struct blkio_group *blkg,
344c1768268STejun Heo 				  struct blkio_policy_type *pol);
345812df48dSDivyesh Shah 
346812df48dSDivyesh Shah #define BLKG_FLAG_FNS(name)						\
347812df48dSDivyesh Shah static inline void blkio_mark_blkg_##name(				\
348812df48dSDivyesh Shah 		struct blkio_group_stats *stats)			\
349812df48dSDivyesh Shah {									\
350812df48dSDivyesh Shah 	stats->flags |= (1 << BLKG_##name);				\
351812df48dSDivyesh Shah }									\
352812df48dSDivyesh Shah static inline void blkio_clear_blkg_##name(				\
353812df48dSDivyesh Shah 		struct blkio_group_stats *stats)			\
354812df48dSDivyesh Shah {									\
355812df48dSDivyesh Shah 	stats->flags &= ~(1 << BLKG_##name);				\
356812df48dSDivyesh Shah }									\
357812df48dSDivyesh Shah static inline int blkio_blkg_##name(struct blkio_group_stats *stats)	\
358812df48dSDivyesh Shah {									\
359812df48dSDivyesh Shah 	return (stats->flags & (1 << BLKG_##name)) != 0;		\
360812df48dSDivyesh Shah }									\
361812df48dSDivyesh Shah 
362812df48dSDivyesh Shah BLKG_FLAG_FNS(waiting)
363812df48dSDivyesh Shah BLKG_FLAG_FNS(idling)
364812df48dSDivyesh Shah BLKG_FLAG_FNS(empty)
365812df48dSDivyesh Shah #undef BLKG_FLAG_FNS
3662868ef7bSVivek Goyal #else
367c1768268STejun Heo static inline void blkiocg_update_avg_queue_size_stats(struct blkio_group *blkg,
368c1768268STejun Heo 			struct blkio_policy_type *pol) { }
3699195291eSDivyesh Shah static inline void blkiocg_update_dequeue_stats(struct blkio_group *blkg,
370c1768268STejun Heo 			struct blkio_policy_type *pol, unsigned long dequeue) { }
371c1768268STejun Heo static inline void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg,
372c1768268STejun Heo 			struct blkio_policy_type *pol) { }
373c1768268STejun Heo static inline void blkiocg_update_idle_time_stats(struct blkio_group *blkg,
374c1768268STejun Heo 			struct blkio_policy_type *pol) { }
375c1768268STejun Heo static inline void blkiocg_set_start_empty_time(struct blkio_group *blkg,
376c1768268STejun Heo 			struct blkio_policy_type *pol) { }
3772868ef7bSVivek Goyal #endif
3782868ef7bSVivek Goyal 
37932e380aeSTejun Heo #ifdef CONFIG_BLK_CGROUP
38031e4c28dSVivek Goyal extern struct blkio_cgroup blkio_root_cgroup;
38131e4c28dSVivek Goyal extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup);
38270087dc3SVivek Goyal extern struct blkio_cgroup *task_blkio_cgroup(struct task_struct *tsk);
38331e4c28dSVivek Goyal extern int blkiocg_del_blkio_group(struct blkio_group *blkg);
384cd1604faSTejun Heo extern struct blkio_group *blkg_lookup(struct blkio_cgroup *blkcg,
385*e8989faeSTejun Heo 				       struct request_queue *q);
386cd1604faSTejun Heo struct blkio_group *blkg_lookup_create(struct blkio_cgroup *blkcg,
387cd1604faSTejun Heo 				       struct request_queue *q,
388cd1604faSTejun Heo 				       enum blkio_policy_id plid,
389cd1604faSTejun Heo 				       bool for_root);
390303a3acbSDivyesh Shah void blkiocg_update_timeslice_used(struct blkio_group *blkg,
391c1768268STejun Heo 				   struct blkio_policy_type *pol,
392167400d3SJustin TerAvest 				   unsigned long time,
393167400d3SJustin TerAvest 				   unsigned long unaccounted_time);
394c1768268STejun Heo void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
395c1768268STejun Heo 				   struct blkio_policy_type *pol,
396c1768268STejun Heo 				   uint64_t bytes, bool direction, bool sync);
39784c124daSDivyesh Shah void blkiocg_update_completion_stats(struct blkio_group *blkg,
398c1768268STejun Heo 				     struct blkio_policy_type *pol,
399c1768268STejun Heo 				     uint64_t start_time,
400c1768268STejun Heo 				     uint64_t io_start_time, bool direction,
401812d4026SDivyesh Shah 				     bool sync);
402c1768268STejun Heo void blkiocg_update_io_merged_stats(struct blkio_group *blkg,
403c1768268STejun Heo 				    struct blkio_policy_type *pol,
404c1768268STejun Heo 				    bool direction, bool sync);
405a11cdaa7SDivyesh Shah void blkiocg_update_io_add_stats(struct blkio_group *blkg,
406c1768268STejun Heo 				 struct blkio_policy_type *pol,
407c1768268STejun Heo 				 struct blkio_group *curr_blkg, bool direction,
408c1768268STejun Heo 				 bool sync);
409a11cdaa7SDivyesh Shah void blkiocg_update_io_remove_stats(struct blkio_group *blkg,
410c1768268STejun Heo 				    struct blkio_policy_type *pol,
411cdc1184cSDivyesh Shah 				    bool direction, bool sync);
41231e4c28dSVivek Goyal #else
4132f5ea477SJens Axboe struct cgroup;
41431e4c28dSVivek Goyal static inline struct blkio_cgroup *
41531e4c28dSVivek Goyal cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; }
41670087dc3SVivek Goyal static inline struct blkio_cgroup *
41770087dc3SVivek Goyal task_blkio_cgroup(struct task_struct *tsk) { return NULL; }
41831e4c28dSVivek Goyal 
41931e4c28dSVivek Goyal static inline int
42031e4c28dSVivek Goyal blkiocg_del_blkio_group(struct blkio_group *blkg) { return 0; }
42131e4c28dSVivek Goyal 
422cd1604faSTejun Heo static inline struct blkio_group *blkg_lookup(struct blkio_cgroup *blkcg,
423cd1604faSTejun Heo 					      void *key) { return NULL; }
424303a3acbSDivyesh Shah static inline void blkiocg_update_timeslice_used(struct blkio_group *blkg,
425c1768268STejun Heo 			struct blkio_policy_type *pol, unsigned long time,
426c1768268STejun Heo 			unsigned long unaccounted_time) { }
42784c124daSDivyesh Shah static inline void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
428c1768268STejun Heo 			struct blkio_policy_type *pol, uint64_t bytes,
429c1768268STejun Heo 			bool direction, bool sync) { }
43084c124daSDivyesh Shah static inline void blkiocg_update_completion_stats(struct blkio_group *blkg,
431c1768268STejun Heo 			struct blkio_policy_type *pol, uint64_t start_time,
432c1768268STejun Heo 			uint64_t io_start_time, bool direction, bool sync) { }
433812d4026SDivyesh Shah static inline void blkiocg_update_io_merged_stats(struct blkio_group *blkg,
434c1768268STejun Heo 			struct blkio_policy_type *pol, bool direction,
435c1768268STejun Heo 			bool sync) { }
436a11cdaa7SDivyesh Shah static inline void blkiocg_update_io_add_stats(struct blkio_group *blkg,
437c1768268STejun Heo 			struct blkio_policy_type *pol,
438c1768268STejun Heo 			struct blkio_group *curr_blkg, bool direction,
439c1768268STejun Heo 			bool sync) { }
440a11cdaa7SDivyesh Shah static inline void blkiocg_update_io_remove_stats(struct blkio_group *blkg,
441c1768268STejun Heo 			struct blkio_policy_type *pol, bool direction,
442c1768268STejun Heo 			bool sync) { }
44331e4c28dSVivek Goyal #endif
44431e4c28dSVivek Goyal #endif /* _BLK_CGROUP_H */
445