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