1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2eea8f41cSTejun Heo #ifndef _BLK_CGROUP_H 3eea8f41cSTejun Heo #define _BLK_CGROUP_H 4eea8f41cSTejun Heo /* 5eea8f41cSTejun Heo * Common Block IO controller cgroup interface 6eea8f41cSTejun Heo * 7eea8f41cSTejun Heo * Based on ideas and code from CFQ, CFS and BFQ: 8eea8f41cSTejun Heo * Copyright (C) 2003 Jens Axboe <[email protected]> 9eea8f41cSTejun Heo * 10eea8f41cSTejun Heo * Copyright (C) 2008 Fabio Checconi <[email protected]> 11eea8f41cSTejun Heo * Paolo Valente <[email protected]> 12eea8f41cSTejun Heo * 13eea8f41cSTejun Heo * Copyright (C) 2009 Vivek Goyal <[email protected]> 14eea8f41cSTejun Heo * Nauman Rafique <[email protected]> 15eea8f41cSTejun Heo */ 16eea8f41cSTejun Heo 17eea8f41cSTejun Heo #include <linux/cgroup.h> 18f7331648STejun Heo #include <linux/percpu.h> 1924bdb8efSTejun Heo #include <linux/percpu_counter.h> 20f7331648STejun Heo #include <linux/u64_stats_sync.h> 21eea8f41cSTejun Heo #include <linux/seq_file.h> 22eea8f41cSTejun Heo #include <linux/radix-tree.h> 23eea8f41cSTejun Heo #include <linux/blkdev.h> 24eea8f41cSTejun Heo #include <linux/atomic.h> 25902ec5b6SShaohua Li #include <linux/kthread.h> 265cdf2e3fSDennis Zhou #include <linux/fs.h> 27eea8f41cSTejun Heo 2824bdb8efSTejun Heo /* percpu_counter batch for blkg_[rw]stats, per-cpu drift doesn't matter */ 2924bdb8efSTejun Heo #define BLKG_STAT_CPU_BATCH (INT_MAX / 2) 3024bdb8efSTejun Heo 31eea8f41cSTejun Heo /* Max limits for throttle policy */ 32eea8f41cSTejun Heo #define THROTL_IOPS_MAX UINT_MAX 33eea8f41cSTejun Heo 34eea8f41cSTejun Heo #ifdef CONFIG_BLK_CGROUP 35eea8f41cSTejun Heo 36f7331648STejun Heo enum blkg_iostat_type { 37f7331648STejun Heo BLKG_IOSTAT_READ, 38f7331648STejun Heo BLKG_IOSTAT_WRITE, 39f7331648STejun Heo BLKG_IOSTAT_DISCARD, 40f7331648STejun Heo 41f7331648STejun Heo BLKG_IOSTAT_NR, 42f7331648STejun Heo }; 43f7331648STejun Heo 44eea8f41cSTejun Heo struct blkcg_gq; 45eea8f41cSTejun Heo 46eea8f41cSTejun Heo struct blkcg { 47eea8f41cSTejun Heo struct cgroup_subsys_state css; 48eea8f41cSTejun Heo spinlock_t lock; 49eea8f41cSTejun Heo 50eea8f41cSTejun Heo struct radix_tree_root blkg_tree; 5155679c8dSBart Van Assche struct blkcg_gq __rcu *blkg_hint; 52eea8f41cSTejun Heo struct hlist_head blkg_list; 53eea8f41cSTejun Heo 5481437648STejun Heo struct blkcg_policy_data *cpd[BLKCG_MAX_POLS]; 5552ebea74STejun Heo 567876f930STejun Heo struct list_head all_blkcgs_node; 5752ebea74STejun Heo #ifdef CONFIG_CGROUP_WRITEBACK 5852ebea74STejun Heo struct list_head cgwb_list; 5959b57717SDennis Zhou (Facebook) refcount_t cgwb_refcnt; 6052ebea74STejun Heo #endif 61eea8f41cSTejun Heo }; 62eea8f41cSTejun Heo 63f7331648STejun Heo struct blkg_iostat { 64f7331648STejun Heo u64 bytes[BLKG_IOSTAT_NR]; 65f7331648STejun Heo u64 ios[BLKG_IOSTAT_NR]; 66f7331648STejun Heo }; 67f7331648STejun Heo 68f7331648STejun Heo struct blkg_iostat_set { 69f7331648STejun Heo struct u64_stats_sync sync; 70f7331648STejun Heo struct blkg_iostat cur; 71f7331648STejun Heo struct blkg_iostat last; 72f7331648STejun Heo }; 73f7331648STejun Heo 74e6269c44STejun Heo /* 75eea8f41cSTejun Heo * A blkcg_gq (blkg) is association between a block cgroup (blkcg) and a 76eea8f41cSTejun Heo * request_queue (q). This is used by blkcg policies which need to track 77eea8f41cSTejun Heo * information per blkcg - q pair. 78eea8f41cSTejun Heo * 79001bea73STejun Heo * There can be multiple active blkcg policies and each blkg:policy pair is 80001bea73STejun Heo * represented by a blkg_policy_data which is allocated and freed by each 81001bea73STejun Heo * policy's pd_alloc/free_fn() methods. A policy can allocate private data 82001bea73STejun Heo * area by allocating larger data structure which embeds blkg_policy_data 83001bea73STejun Heo * at the beginning. 84eea8f41cSTejun Heo */ 85eea8f41cSTejun Heo struct blkg_policy_data { 86eea8f41cSTejun Heo /* the blkg and policy id this per-policy data belongs to */ 87eea8f41cSTejun Heo struct blkcg_gq *blkg; 88eea8f41cSTejun Heo int plid; 89eea8f41cSTejun Heo }; 90eea8f41cSTejun Heo 91e4bc13adSLinus Torvalds /* 92e4a9bde9STejun Heo * Policies that need to keep per-blkcg data which is independent from any 93e4a9bde9STejun Heo * request_queue associated to it should implement cpd_alloc/free_fn() 94e4a9bde9STejun Heo * methods. A policy can allocate private data area by allocating larger 95e4a9bde9STejun Heo * data structure which embeds blkcg_policy_data at the beginning. 96e4a9bde9STejun Heo * cpd_init() is invoked to let each policy handle per-blkcg data. 97e4bc13adSLinus Torvalds */ 98e4bc13adSLinus Torvalds struct blkcg_policy_data { 9981437648STejun Heo /* the blkcg and policy id this per-policy data belongs to */ 10081437648STejun Heo struct blkcg *blkcg; 101e4bc13adSLinus Torvalds int plid; 102e4bc13adSLinus Torvalds }; 103e4bc13adSLinus Torvalds 104eea8f41cSTejun Heo /* association between a blk cgroup and a request queue */ 105eea8f41cSTejun Heo struct blkcg_gq { 106eea8f41cSTejun Heo /* Pointer to the associated request_queue */ 107eea8f41cSTejun Heo struct request_queue *q; 108eea8f41cSTejun Heo struct list_head q_node; 109eea8f41cSTejun Heo struct hlist_node blkcg_node; 110eea8f41cSTejun Heo struct blkcg *blkcg; 111eea8f41cSTejun Heo 112ce7acfeaSTejun Heo /* 113ce7acfeaSTejun Heo * Each blkg gets congested separately and the congestion state is 114ce7acfeaSTejun Heo * propagated to the matching bdi_writeback_congested. 115ce7acfeaSTejun Heo */ 116ce7acfeaSTejun Heo struct bdi_writeback_congested *wb_congested; 117ce7acfeaSTejun Heo 118eea8f41cSTejun Heo /* all non-root blkcg_gq's are guaranteed to have access to parent */ 119eea8f41cSTejun Heo struct blkcg_gq *parent; 120eea8f41cSTejun Heo 121eea8f41cSTejun Heo /* reference count */ 1227fcf2b03SDennis Zhou struct percpu_ref refcnt; 123eea8f41cSTejun Heo 124eea8f41cSTejun Heo /* is this blkg online? protected by both blkcg and q locks */ 125eea8f41cSTejun Heo bool online; 126eea8f41cSTejun Heo 127f7331648STejun Heo struct blkg_iostat_set __percpu *iostat_cpu; 128f7331648STejun Heo struct blkg_iostat_set iostat; 12977ea7338STejun Heo 130eea8f41cSTejun Heo struct blkg_policy_data *pd[BLKCG_MAX_POLS]; 131eea8f41cSTejun Heo 132d3f77dfdSTejun Heo spinlock_t async_bio_lock; 133d3f77dfdSTejun Heo struct bio_list async_bios; 134d3f77dfdSTejun Heo struct work_struct async_bio_work; 135d09d8df3SJosef Bacik 136d09d8df3SJosef Bacik atomic_t use_delay; 137d09d8df3SJosef Bacik atomic64_t delay_nsec; 138d09d8df3SJosef Bacik atomic64_t delay_start; 139d09d8df3SJosef Bacik u64 last_delay; 140d09d8df3SJosef Bacik int last_use; 141d3f77dfdSTejun Heo 142d3f77dfdSTejun Heo struct rcu_head rcu_head; 143eea8f41cSTejun Heo }; 144eea8f41cSTejun Heo 145e4a9bde9STejun Heo typedef struct blkcg_policy_data *(blkcg_pol_alloc_cpd_fn)(gfp_t gfp); 14681437648STejun Heo typedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd); 147e4a9bde9STejun Heo typedef void (blkcg_pol_free_cpd_fn)(struct blkcg_policy_data *cpd); 14869d7fde5STejun Heo typedef void (blkcg_pol_bind_cpd_fn)(struct blkcg_policy_data *cpd); 149cf09a8eeSTejun Heo typedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp, 150cf09a8eeSTejun Heo struct request_queue *q, struct blkcg *blkcg); 151a9520cd6STejun Heo typedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd); 152a9520cd6STejun Heo typedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd); 153a9520cd6STejun Heo typedef void (blkcg_pol_offline_pd_fn)(struct blkg_policy_data *pd); 154001bea73STejun Heo typedef void (blkcg_pol_free_pd_fn)(struct blkg_policy_data *pd); 155a9520cd6STejun Heo typedef void (blkcg_pol_reset_pd_stats_fn)(struct blkg_policy_data *pd); 156903d23f0SJosef Bacik typedef size_t (blkcg_pol_stat_pd_fn)(struct blkg_policy_data *pd, char *buf, 157903d23f0SJosef Bacik size_t size); 158eea8f41cSTejun Heo 159eea8f41cSTejun Heo struct blkcg_policy { 160eea8f41cSTejun Heo int plid; 161eea8f41cSTejun Heo /* cgroup files for the policy */ 1622ee867dcSTejun Heo struct cftype *dfl_cftypes; 163880f50e2STejun Heo struct cftype *legacy_cftypes; 164eea8f41cSTejun Heo 165eea8f41cSTejun Heo /* operations */ 166e4a9bde9STejun Heo blkcg_pol_alloc_cpd_fn *cpd_alloc_fn; 167e4bc13adSLinus Torvalds blkcg_pol_init_cpd_fn *cpd_init_fn; 168e4a9bde9STejun Heo blkcg_pol_free_cpd_fn *cpd_free_fn; 16969d7fde5STejun Heo blkcg_pol_bind_cpd_fn *cpd_bind_fn; 170e4a9bde9STejun Heo 171001bea73STejun Heo blkcg_pol_alloc_pd_fn *pd_alloc_fn; 172eea8f41cSTejun Heo blkcg_pol_init_pd_fn *pd_init_fn; 173eea8f41cSTejun Heo blkcg_pol_online_pd_fn *pd_online_fn; 174eea8f41cSTejun Heo blkcg_pol_offline_pd_fn *pd_offline_fn; 175001bea73STejun Heo blkcg_pol_free_pd_fn *pd_free_fn; 176eea8f41cSTejun Heo blkcg_pol_reset_pd_stats_fn *pd_reset_stats_fn; 177903d23f0SJosef Bacik blkcg_pol_stat_pd_fn *pd_stat_fn; 178eea8f41cSTejun Heo }; 179eea8f41cSTejun Heo 180eea8f41cSTejun Heo extern struct blkcg blkcg_root; 181496d5e75STejun Heo extern struct cgroup_subsys_state * const blkcg_root_css; 18207b0fdecSTejun Heo extern bool blkcg_debug_stats; 183eea8f41cSTejun Heo 18424f29046STejun Heo struct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg, 18524f29046STejun Heo struct request_queue *q, bool update_hint); 186b978962aSDennis Zhou struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg, 187b978962aSDennis Zhou struct request_queue *q); 188eea8f41cSTejun Heo struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg, 189eea8f41cSTejun Heo struct request_queue *q); 190eea8f41cSTejun Heo int blkcg_init_queue(struct request_queue *q); 191eea8f41cSTejun Heo void blkcg_drain_queue(struct request_queue *q); 192eea8f41cSTejun Heo void blkcg_exit_queue(struct request_queue *q); 193eea8f41cSTejun Heo 194eea8f41cSTejun Heo /* Blkio controller policy registration */ 195eea8f41cSTejun Heo int blkcg_policy_register(struct blkcg_policy *pol); 196eea8f41cSTejun Heo void blkcg_policy_unregister(struct blkcg_policy *pol); 197eea8f41cSTejun Heo int blkcg_activate_policy(struct request_queue *q, 198eea8f41cSTejun Heo const struct blkcg_policy *pol); 199eea8f41cSTejun Heo void blkcg_deactivate_policy(struct request_queue *q, 200eea8f41cSTejun Heo const struct blkcg_policy *pol); 201eea8f41cSTejun Heo 202dd165eb3STejun Heo const char *blkg_dev_name(struct blkcg_gq *blkg); 203eea8f41cSTejun Heo void blkcg_print_blkgs(struct seq_file *sf, struct blkcg *blkcg, 204eea8f41cSTejun Heo u64 (*prfill)(struct seq_file *, 205eea8f41cSTejun Heo struct blkg_policy_data *, int), 206eea8f41cSTejun Heo const struct blkcg_policy *pol, int data, 207eea8f41cSTejun Heo bool show_total); 208eea8f41cSTejun Heo u64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v); 209eea8f41cSTejun Heo 210eea8f41cSTejun Heo struct blkg_conf_ctx { 211eea8f41cSTejun Heo struct gendisk *disk; 212eea8f41cSTejun Heo struct blkcg_gq *blkg; 21336aa9e5fSTejun Heo char *body; 214eea8f41cSTejun Heo }; 215eea8f41cSTejun Heo 216015d254cSTejun Heo struct gendisk *blkcg_conf_get_disk(char **inputp); 217eea8f41cSTejun Heo int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, 21836aa9e5fSTejun Heo char *input, struct blkg_conf_ctx *ctx); 219eea8f41cSTejun Heo void blkg_conf_finish(struct blkg_conf_ctx *ctx); 220eea8f41cSTejun Heo 2210fe061b9SDennis Zhou /** 2220fe061b9SDennis Zhou * blkcg_css - find the current css 2230fe061b9SDennis Zhou * 2240fe061b9SDennis Zhou * Find the css associated with either the kthread or the current task. 2250fe061b9SDennis Zhou * This may return a dying css, so it is up to the caller to use tryget logic 2260fe061b9SDennis Zhou * to confirm it is alive and well. 2270fe061b9SDennis Zhou */ 2280fe061b9SDennis Zhou static inline struct cgroup_subsys_state *blkcg_css(void) 2290fe061b9SDennis Zhou { 2300fe061b9SDennis Zhou struct cgroup_subsys_state *css; 2310fe061b9SDennis Zhou 2320fe061b9SDennis Zhou css = kthread_blkcg(); 2330fe061b9SDennis Zhou if (css) 2340fe061b9SDennis Zhou return css; 2350fe061b9SDennis Zhou return task_css(current, io_cgrp_id); 2360fe061b9SDennis Zhou } 2370fe061b9SDennis Zhou 238eea8f41cSTejun Heo static inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *css) 239eea8f41cSTejun Heo { 240eea8f41cSTejun Heo return css ? container_of(css, struct blkcg, css) : NULL; 241eea8f41cSTejun Heo } 242eea8f41cSTejun Heo 2430fe061b9SDennis Zhou /** 2440fe061b9SDennis Zhou * __bio_blkcg - internal, inconsistent version to get blkcg 2450fe061b9SDennis Zhou * 2460fe061b9SDennis Zhou * DO NOT USE. 2470fe061b9SDennis Zhou * This function is inconsistent and consequently is dangerous to use. The 2480fe061b9SDennis Zhou * first part of the function returns a blkcg where a reference is owned by the 2490fe061b9SDennis Zhou * bio. This means it does not need to be rcu protected as it cannot go away 2500fe061b9SDennis Zhou * with the bio owning a reference to it. However, the latter potentially gets 2510fe061b9SDennis Zhou * it from task_css(). This can race against task migration and the cgroup 2520fe061b9SDennis Zhou * dying. It is also semantically different as it must be called rcu protected 2530fe061b9SDennis Zhou * and is susceptible to failure when trying to get a reference to it. 2540fe061b9SDennis Zhou * Therefore, it is not ok to assume that *_get() will always succeed on the 2550fe061b9SDennis Zhou * blkcg returned here. 2560fe061b9SDennis Zhou */ 2570fe061b9SDennis Zhou static inline struct blkcg *__bio_blkcg(struct bio *bio) 25827e6fa99SDennis Zhou (Facebook) { 259db6638d7SDennis Zhou if (bio && bio->bi_blkg) 260db6638d7SDennis Zhou return bio->bi_blkg->blkcg; 2610fe061b9SDennis Zhou return css_to_blkcg(blkcg_css()); 2620fe061b9SDennis Zhou } 2630fe061b9SDennis Zhou 2640fe061b9SDennis Zhou /** 2650fe061b9SDennis Zhou * bio_blkcg - grab the blkcg associated with a bio 2660fe061b9SDennis Zhou * @bio: target bio 2670fe061b9SDennis Zhou * 2680fe061b9SDennis Zhou * This returns the blkcg associated with a bio, %NULL if not associated. 2690fe061b9SDennis Zhou * Callers are expected to either handle %NULL or know association has been 2700fe061b9SDennis Zhou * done prior to calling this. 2710fe061b9SDennis Zhou */ 2720fe061b9SDennis Zhou static inline struct blkcg *bio_blkcg(struct bio *bio) 2730fe061b9SDennis Zhou { 274db6638d7SDennis Zhou if (bio && bio->bi_blkg) 275db6638d7SDennis Zhou return bio->bi_blkg->blkcg; 2760fe061b9SDennis Zhou return NULL; 277fd383c2dSTejun Heo } 278fd383c2dSTejun Heo 279d09d8df3SJosef Bacik static inline bool blk_cgroup_congested(void) 280d09d8df3SJosef Bacik { 281d09d8df3SJosef Bacik struct cgroup_subsys_state *css; 282d09d8df3SJosef Bacik bool ret = false; 283d09d8df3SJosef Bacik 284d09d8df3SJosef Bacik rcu_read_lock(); 285d09d8df3SJosef Bacik css = kthread_blkcg(); 286d09d8df3SJosef Bacik if (!css) 287d09d8df3SJosef Bacik css = task_css(current, io_cgrp_id); 288d09d8df3SJosef Bacik while (css) { 289d09d8df3SJosef Bacik if (atomic_read(&css->cgroup->congestion_count)) { 290d09d8df3SJosef Bacik ret = true; 291d09d8df3SJosef Bacik break; 292d09d8df3SJosef Bacik } 293d09d8df3SJosef Bacik css = css->parent; 294d09d8df3SJosef Bacik } 295d09d8df3SJosef Bacik rcu_read_unlock(); 296d09d8df3SJosef Bacik return ret; 297d09d8df3SJosef Bacik } 298d09d8df3SJosef Bacik 299eea8f41cSTejun Heo /** 300c7c98fd3SJosef Bacik * bio_issue_as_root_blkg - see if this bio needs to be issued as root blkg 301c7c98fd3SJosef Bacik * @return: true if this bio needs to be submitted with the root blkg context. 302c7c98fd3SJosef Bacik * 303c7c98fd3SJosef Bacik * In order to avoid priority inversions we sometimes need to issue a bio as if 304c7c98fd3SJosef Bacik * it were attached to the root blkg, and then backcharge to the actual owning 305c7c98fd3SJosef Bacik * blkg. The idea is we do bio_blkcg() to look up the actual context for the 306c7c98fd3SJosef Bacik * bio and attach the appropriate blkg to the bio. Then we call this helper and 307c7c98fd3SJosef Bacik * if it is true run with the root blkg for that queue and then do any 308c7c98fd3SJosef Bacik * backcharging to the originating cgroup once the io is complete. 309c7c98fd3SJosef Bacik */ 310c7c98fd3SJosef Bacik static inline bool bio_issue_as_root_blkg(struct bio *bio) 311c7c98fd3SJosef Bacik { 3120d1e0c7cSJosef Bacik return (bio->bi_opf & (REQ_META | REQ_SWAP)) != 0; 313c7c98fd3SJosef Bacik } 314c7c98fd3SJosef Bacik 315c7c98fd3SJosef Bacik /** 316eea8f41cSTejun Heo * blkcg_parent - get the parent of a blkcg 317eea8f41cSTejun Heo * @blkcg: blkcg of interest 318eea8f41cSTejun Heo * 319eea8f41cSTejun Heo * Return the parent blkcg of @blkcg. Can be called anytime. 320eea8f41cSTejun Heo */ 321eea8f41cSTejun Heo static inline struct blkcg *blkcg_parent(struct blkcg *blkcg) 322eea8f41cSTejun Heo { 323eea8f41cSTejun Heo return css_to_blkcg(blkcg->css.parent); 324eea8f41cSTejun Heo } 325eea8f41cSTejun Heo 326eea8f41cSTejun Heo /** 32724f29046STejun Heo * __blkg_lookup - internal version of blkg_lookup() 32824f29046STejun Heo * @blkcg: blkcg of interest 32924f29046STejun Heo * @q: request_queue of interest 33024f29046STejun Heo * @update_hint: whether to update lookup hint with the result or not 33124f29046STejun Heo * 33224f29046STejun Heo * This is internal version and shouldn't be used by policy 33324f29046STejun Heo * implementations. Looks up blkgs for the @blkcg - @q pair regardless of 33424f29046STejun Heo * @q's bypass state. If @update_hint is %true, the caller should be 33524f29046STejun Heo * holding @q->queue_lock and lookup hint is updated on success. 33624f29046STejun Heo */ 33724f29046STejun Heo static inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg, 33824f29046STejun Heo struct request_queue *q, 33924f29046STejun Heo bool update_hint) 34024f29046STejun Heo { 34124f29046STejun Heo struct blkcg_gq *blkg; 34224f29046STejun Heo 34385b6bc9dSTejun Heo if (blkcg == &blkcg_root) 34485b6bc9dSTejun Heo return q->root_blkg; 34585b6bc9dSTejun Heo 34624f29046STejun Heo blkg = rcu_dereference(blkcg->blkg_hint); 34724f29046STejun Heo if (blkg && blkg->q == q) 34824f29046STejun Heo return blkg; 34924f29046STejun Heo 35024f29046STejun Heo return blkg_lookup_slowpath(blkcg, q, update_hint); 35124f29046STejun Heo } 35224f29046STejun Heo 35324f29046STejun Heo /** 35424f29046STejun Heo * blkg_lookup - lookup blkg for the specified blkcg - q pair 35524f29046STejun Heo * @blkcg: blkcg of interest 35624f29046STejun Heo * @q: request_queue of interest 35724f29046STejun Heo * 35824f29046STejun Heo * Lookup blkg for the @blkcg - @q pair. This function should be called 359012d4a65SBart Van Assche * under RCU read lock. 36024f29046STejun Heo */ 36124f29046STejun Heo static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, 36224f29046STejun Heo struct request_queue *q) 36324f29046STejun Heo { 36424f29046STejun Heo WARN_ON_ONCE(!rcu_read_lock_held()); 36524f29046STejun Heo return __blkg_lookup(blkcg, q, false); 36624f29046STejun Heo } 36724f29046STejun Heo 36824f29046STejun Heo /** 369b86d865cSBart Van Assche * blk_queue_root_blkg - return blkg for the (blkcg_root, @q) pair 3706bad9b21SBart Van Assche * @q: request_queue of interest 3716bad9b21SBart Van Assche * 3726bad9b21SBart Van Assche * Lookup blkg for @q at the root level. See also blkg_lookup(). 3736bad9b21SBart Van Assche */ 374b86d865cSBart Van Assche static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q) 3756bad9b21SBart Van Assche { 376b86d865cSBart Van Assche return q->root_blkg; 3776bad9b21SBart Van Assche } 3786bad9b21SBart Van Assche 3796bad9b21SBart Van Assche /** 380eea8f41cSTejun Heo * blkg_to_pdata - get policy private data 381eea8f41cSTejun Heo * @blkg: blkg of interest 382eea8f41cSTejun Heo * @pol: policy of interest 383eea8f41cSTejun Heo * 384eea8f41cSTejun Heo * Return pointer to private data associated with the @blkg-@pol pair. 385eea8f41cSTejun Heo */ 386eea8f41cSTejun Heo static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg, 387eea8f41cSTejun Heo struct blkcg_policy *pol) 388eea8f41cSTejun Heo { 389eea8f41cSTejun Heo return blkg ? blkg->pd[pol->plid] : NULL; 390eea8f41cSTejun Heo } 391eea8f41cSTejun Heo 392e4bc13adSLinus Torvalds static inline struct blkcg_policy_data *blkcg_to_cpd(struct blkcg *blkcg, 393e4bc13adSLinus Torvalds struct blkcg_policy *pol) 394e4bc13adSLinus Torvalds { 39581437648STejun Heo return blkcg ? blkcg->cpd[pol->plid] : NULL; 396e4bc13adSLinus Torvalds } 397e4bc13adSLinus Torvalds 398eea8f41cSTejun Heo /** 399eea8f41cSTejun Heo * pdata_to_blkg - get blkg associated with policy private data 400eea8f41cSTejun Heo * @pd: policy private data of interest 401eea8f41cSTejun Heo * 402eea8f41cSTejun Heo * @pd is policy private data. Determine the blkg it's associated with. 403eea8f41cSTejun Heo */ 404eea8f41cSTejun Heo static inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd) 405eea8f41cSTejun Heo { 406eea8f41cSTejun Heo return pd ? pd->blkg : NULL; 407eea8f41cSTejun Heo } 408eea8f41cSTejun Heo 40981437648STejun Heo static inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd) 41081437648STejun Heo { 41181437648STejun Heo return cpd ? cpd->blkcg : NULL; 41281437648STejun Heo } 41381437648STejun Heo 41459b57717SDennis Zhou (Facebook) extern void blkcg_destroy_blkgs(struct blkcg *blkcg); 41559b57717SDennis Zhou (Facebook) 41659b57717SDennis Zhou (Facebook) #ifdef CONFIG_CGROUP_WRITEBACK 41759b57717SDennis Zhou (Facebook) 41859b57717SDennis Zhou (Facebook) /** 41959b57717SDennis Zhou (Facebook) * blkcg_cgwb_get - get a reference for blkcg->cgwb_list 42059b57717SDennis Zhou (Facebook) * @blkcg: blkcg of interest 42159b57717SDennis Zhou (Facebook) * 42259b57717SDennis Zhou (Facebook) * This is used to track the number of active wb's related to a blkcg. 42359b57717SDennis Zhou (Facebook) */ 42459b57717SDennis Zhou (Facebook) static inline void blkcg_cgwb_get(struct blkcg *blkcg) 42559b57717SDennis Zhou (Facebook) { 42659b57717SDennis Zhou (Facebook) refcount_inc(&blkcg->cgwb_refcnt); 42759b57717SDennis Zhou (Facebook) } 42859b57717SDennis Zhou (Facebook) 42959b57717SDennis Zhou (Facebook) /** 43059b57717SDennis Zhou (Facebook) * blkcg_cgwb_put - put a reference for @blkcg->cgwb_list 43159b57717SDennis Zhou (Facebook) * @blkcg: blkcg of interest 43259b57717SDennis Zhou (Facebook) * 43359b57717SDennis Zhou (Facebook) * This is used to track the number of active wb's related to a blkcg. 43459b57717SDennis Zhou (Facebook) * When this count goes to zero, all active wb has finished so the 43559b57717SDennis Zhou (Facebook) * blkcg can continue destruction by calling blkcg_destroy_blkgs(). 43659b57717SDennis Zhou (Facebook) * This work may occur in cgwb_release_workfn() on the cgwb_release 43759b57717SDennis Zhou (Facebook) * workqueue. 43859b57717SDennis Zhou (Facebook) */ 43959b57717SDennis Zhou (Facebook) static inline void blkcg_cgwb_put(struct blkcg *blkcg) 44059b57717SDennis Zhou (Facebook) { 44159b57717SDennis Zhou (Facebook) if (refcount_dec_and_test(&blkcg->cgwb_refcnt)) 44259b57717SDennis Zhou (Facebook) blkcg_destroy_blkgs(blkcg); 44359b57717SDennis Zhou (Facebook) } 44459b57717SDennis Zhou (Facebook) 44559b57717SDennis Zhou (Facebook) #else 44659b57717SDennis Zhou (Facebook) 44759b57717SDennis Zhou (Facebook) static inline void blkcg_cgwb_get(struct blkcg *blkcg) { } 44859b57717SDennis Zhou (Facebook) 44959b57717SDennis Zhou (Facebook) static inline void blkcg_cgwb_put(struct blkcg *blkcg) 45059b57717SDennis Zhou (Facebook) { 45159b57717SDennis Zhou (Facebook) /* wb isn't being accounted, so trigger destruction right away */ 45259b57717SDennis Zhou (Facebook) blkcg_destroy_blkgs(blkcg); 45359b57717SDennis Zhou (Facebook) } 45459b57717SDennis Zhou (Facebook) 45559b57717SDennis Zhou (Facebook) #endif 45659b57717SDennis Zhou (Facebook) 457eea8f41cSTejun Heo /** 458eea8f41cSTejun Heo * blkg_path - format cgroup path of blkg 459eea8f41cSTejun Heo * @blkg: blkg of interest 460eea8f41cSTejun Heo * @buf: target buffer 461eea8f41cSTejun Heo * @buflen: target buffer length 462eea8f41cSTejun Heo * 463eea8f41cSTejun Heo * Format the path of the cgroup of @blkg into @buf. 464eea8f41cSTejun Heo */ 465eea8f41cSTejun Heo static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen) 466eea8f41cSTejun Heo { 4674c737b41STejun Heo return cgroup_path(blkg->blkcg->css.cgroup, buf, buflen); 468eea8f41cSTejun Heo } 469eea8f41cSTejun Heo 470eea8f41cSTejun Heo /** 471eea8f41cSTejun Heo * blkg_get - get a blkg reference 472eea8f41cSTejun Heo * @blkg: blkg to get 473eea8f41cSTejun Heo * 474eea8f41cSTejun Heo * The caller should be holding an existing reference. 475eea8f41cSTejun Heo */ 476eea8f41cSTejun Heo static inline void blkg_get(struct blkcg_gq *blkg) 477eea8f41cSTejun Heo { 4787fcf2b03SDennis Zhou percpu_ref_get(&blkg->refcnt); 479eea8f41cSTejun Heo } 480eea8f41cSTejun Heo 481d09d8df3SJosef Bacik /** 4827754f669SDennis Zhou * blkg_tryget - try and get a blkg reference 483d09d8df3SJosef Bacik * @blkg: blkg to get 484d09d8df3SJosef Bacik * 485d09d8df3SJosef Bacik * This is for use when doing an RCU lookup of the blkg. We may be in the midst 486d09d8df3SJosef Bacik * of freeing this blkg, so we can only use it if the refcnt is not zero. 487d09d8df3SJosef Bacik */ 4887754f669SDennis Zhou static inline bool blkg_tryget(struct blkcg_gq *blkg) 489d09d8df3SJosef Bacik { 4906ab21879SDennis Zhou return blkg && percpu_ref_tryget(&blkg->refcnt); 49107b05bccSDennis Zhou (Facebook) } 492d09d8df3SJosef Bacik 493beea9da0SDennis Zhou /** 4947754f669SDennis Zhou * blkg_tryget_closest - try and get a blkg ref on the closet blkg 495beea9da0SDennis Zhou * @blkg: blkg to get 496beea9da0SDennis Zhou * 4976ab21879SDennis Zhou * This needs to be called rcu protected. As the failure mode here is to walk 4986ab21879SDennis Zhou * up the blkg tree, this ensure that the blkg->parent pointers are always 4996ab21879SDennis Zhou * valid. This returns the blkg that it ended up taking a reference on or %NULL 5006ab21879SDennis Zhou * if no reference was taken. 501beea9da0SDennis Zhou */ 5027754f669SDennis Zhou static inline struct blkcg_gq *blkg_tryget_closest(struct blkcg_gq *blkg) 503beea9da0SDennis Zhou { 5046ab21879SDennis Zhou struct blkcg_gq *ret_blkg = NULL; 505beea9da0SDennis Zhou 5066ab21879SDennis Zhou WARN_ON_ONCE(!rcu_read_lock_held()); 5076ab21879SDennis Zhou 5086ab21879SDennis Zhou while (blkg) { 5096ab21879SDennis Zhou if (blkg_tryget(blkg)) { 5106ab21879SDennis Zhou ret_blkg = blkg; 5116ab21879SDennis Zhou break; 5126ab21879SDennis Zhou } 5136ab21879SDennis Zhou blkg = blkg->parent; 5146ab21879SDennis Zhou } 5156ab21879SDennis Zhou 5166ab21879SDennis Zhou return ret_blkg; 517beea9da0SDennis Zhou } 518b5f2954dSDennis Zhou 519eea8f41cSTejun Heo /** 520eea8f41cSTejun Heo * blkg_put - put a blkg reference 521eea8f41cSTejun Heo * @blkg: blkg to put 522eea8f41cSTejun Heo */ 523eea8f41cSTejun Heo static inline void blkg_put(struct blkcg_gq *blkg) 524eea8f41cSTejun Heo { 5257fcf2b03SDennis Zhou percpu_ref_put(&blkg->refcnt); 526eea8f41cSTejun Heo } 527eea8f41cSTejun Heo 528eea8f41cSTejun Heo /** 529eea8f41cSTejun Heo * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants 530eea8f41cSTejun Heo * @d_blkg: loop cursor pointing to the current descendant 531eea8f41cSTejun Heo * @pos_css: used for iteration 532eea8f41cSTejun Heo * @p_blkg: target blkg to walk descendants of 533eea8f41cSTejun Heo * 534eea8f41cSTejun Heo * Walk @c_blkg through the descendants of @p_blkg. Must be used with RCU 535eea8f41cSTejun Heo * read locked. If called under either blkcg or queue lock, the iteration 536eea8f41cSTejun Heo * is guaranteed to include all and only online blkgs. The caller may 537eea8f41cSTejun Heo * update @pos_css by calling css_rightmost_descendant() to skip subtree. 538eea8f41cSTejun Heo * @p_blkg is included in the iteration and the first node to be visited. 539eea8f41cSTejun Heo */ 540eea8f41cSTejun Heo #define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg) \ 541eea8f41cSTejun Heo css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css) \ 542eea8f41cSTejun Heo if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \ 543eea8f41cSTejun Heo (p_blkg)->q, false))) 544eea8f41cSTejun Heo 545eea8f41cSTejun Heo /** 546eea8f41cSTejun Heo * blkg_for_each_descendant_post - post-order walk of a blkg's descendants 547eea8f41cSTejun Heo * @d_blkg: loop cursor pointing to the current descendant 548eea8f41cSTejun Heo * @pos_css: used for iteration 549eea8f41cSTejun Heo * @p_blkg: target blkg to walk descendants of 550eea8f41cSTejun Heo * 551eea8f41cSTejun Heo * Similar to blkg_for_each_descendant_pre() but performs post-order 552eea8f41cSTejun Heo * traversal instead. Synchronization rules are the same. @p_blkg is 553eea8f41cSTejun Heo * included in the iteration and the last node to be visited. 554eea8f41cSTejun Heo */ 555eea8f41cSTejun Heo #define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg) \ 556eea8f41cSTejun Heo css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css) \ 557eea8f41cSTejun Heo if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \ 558eea8f41cSTejun Heo (p_blkg)->q, false))) 559eea8f41cSTejun Heo 560ae118896STejun Heo #ifdef CONFIG_BLK_DEV_THROTTLING 561ae118896STejun Heo extern bool blk_throtl_bio(struct request_queue *q, struct blkcg_gq *blkg, 562ae118896STejun Heo struct bio *bio); 563ae118896STejun Heo #else 564ae118896STejun Heo static inline bool blk_throtl_bio(struct request_queue *q, struct blkcg_gq *blkg, 565ae118896STejun Heo struct bio *bio) { return false; } 566ae118896STejun Heo #endif 567ae118896STejun Heo 568d3f77dfdSTejun Heo bool __blkcg_punt_bio_submit(struct bio *bio); 569d3f77dfdSTejun Heo 570d3f77dfdSTejun Heo static inline bool blkcg_punt_bio_submit(struct bio *bio) 571d3f77dfdSTejun Heo { 572d3f77dfdSTejun Heo if (bio->bi_opf & REQ_CGROUP_PUNT) 573d3f77dfdSTejun Heo return __blkcg_punt_bio_submit(bio); 574d3f77dfdSTejun Heo else 575d3f77dfdSTejun Heo return false; 576d3f77dfdSTejun Heo } 577e439bedfSDennis Zhou 578e439bedfSDennis Zhou static inline void blkcg_bio_issue_init(struct bio *bio) 579e439bedfSDennis Zhou { 580e439bedfSDennis Zhou bio_issue_init(&bio->bi_issue, bio_sectors(bio)); 581e439bedfSDennis Zhou } 582e439bedfSDennis Zhou 583ae118896STejun Heo static inline bool blkcg_bio_issue_check(struct request_queue *q, 584ae118896STejun Heo struct bio *bio) 585ae118896STejun Heo { 586ae118896STejun Heo struct blkcg_gq *blkg; 587ae118896STejun Heo bool throtl = false; 588ae118896STejun Heo 5894705de73SDennis Zhou rcu_read_lock(); 5904705de73SDennis Zhou 5915cdf2e3fSDennis Zhou if (!bio->bi_blkg) { 5925cdf2e3fSDennis Zhou char b[BDEVNAME_SIZE]; 593ae118896STejun Heo 5945cdf2e3fSDennis Zhou WARN_ONCE(1, 5955cdf2e3fSDennis Zhou "no blkg associated for bio on block-device: %s\n", 5965cdf2e3fSDennis Zhou bio_devname(bio, b)); 5975cdf2e3fSDennis Zhou bio_associate_blkg(bio); 5985cdf2e3fSDennis Zhou } 5995cdf2e3fSDennis Zhou 6005cdf2e3fSDennis Zhou blkg = bio->bi_blkg; 601ae118896STejun Heo 602ae118896STejun Heo throtl = blk_throtl_bio(q, blkg, bio); 603ae118896STejun Heo 60477ea7338STejun Heo if (!throtl) { 605f7331648STejun Heo struct blkg_iostat_set *bis; 606f7331648STejun Heo int rwd, cpu; 607f7331648STejun Heo 608f7331648STejun Heo if (op_is_discard(bio->bi_opf)) 609f7331648STejun Heo rwd = BLKG_IOSTAT_DISCARD; 610f7331648STejun Heo else if (op_is_write(bio->bi_opf)) 611f7331648STejun Heo rwd = BLKG_IOSTAT_WRITE; 612f7331648STejun Heo else 613f7331648STejun Heo rwd = BLKG_IOSTAT_READ; 614f7331648STejun Heo 615f7331648STejun Heo cpu = get_cpu(); 616f7331648STejun Heo bis = per_cpu_ptr(blkg->iostat_cpu, cpu); 617f7331648STejun Heo u64_stats_update_begin(&bis->sync); 618f7331648STejun Heo 619c454edc2SJosef Bacik /* 620c454edc2SJosef Bacik * If the bio is flagged with BIO_QUEUE_ENTERED it means this 621c454edc2SJosef Bacik * is a split bio and we would have already accounted for the 622c454edc2SJosef Bacik * size of the bio. 623c454edc2SJosef Bacik */ 624c454edc2SJosef Bacik if (!bio_flagged(bio, BIO_QUEUE_ENTERED)) 625f7331648STejun Heo bis->cur.bytes[rwd] += bio->bi_iter.bi_size; 626f7331648STejun Heo bis->cur.ios[rwd]++; 627f7331648STejun Heo 628f7331648STejun Heo u64_stats_update_end(&bis->sync); 629*496074f9STejun Heo if (cgroup_subsys_on_dfl(io_cgrp_subsys)) 630f7331648STejun Heo cgroup_rstat_updated(blkg->blkcg->css.cgroup, cpu); 631f7331648STejun Heo put_cpu(); 63277ea7338STejun Heo } 63377ea7338STejun Heo 634e439bedfSDennis Zhou blkcg_bio_issue_init(bio); 635e439bedfSDennis Zhou 6364705de73SDennis Zhou rcu_read_unlock(); 637ae118896STejun Heo return !throtl; 638ae118896STejun Heo } 639ae118896STejun Heo 640d09d8df3SJosef Bacik static inline void blkcg_use_delay(struct blkcg_gq *blkg) 641d09d8df3SJosef Bacik { 642d09d8df3SJosef Bacik if (atomic_add_return(1, &blkg->use_delay) == 1) 643d09d8df3SJosef Bacik atomic_inc(&blkg->blkcg->css.cgroup->congestion_count); 644d09d8df3SJosef Bacik } 645d09d8df3SJosef Bacik 646d09d8df3SJosef Bacik static inline int blkcg_unuse_delay(struct blkcg_gq *blkg) 647d09d8df3SJosef Bacik { 648d09d8df3SJosef Bacik int old = atomic_read(&blkg->use_delay); 649d09d8df3SJosef Bacik 650d09d8df3SJosef Bacik if (old == 0) 651d09d8df3SJosef Bacik return 0; 652d09d8df3SJosef Bacik 653d09d8df3SJosef Bacik /* 654d09d8df3SJosef Bacik * We do this song and dance because we can race with somebody else 655d09d8df3SJosef Bacik * adding or removing delay. If we just did an atomic_dec we'd end up 656d09d8df3SJosef Bacik * negative and we'd already be in trouble. We need to subtract 1 and 657d09d8df3SJosef Bacik * then check to see if we were the last delay so we can drop the 658d09d8df3SJosef Bacik * congestion count on the cgroup. 659d09d8df3SJosef Bacik */ 660d09d8df3SJosef Bacik while (old) { 661d09d8df3SJosef Bacik int cur = atomic_cmpxchg(&blkg->use_delay, old, old - 1); 662d09d8df3SJosef Bacik if (cur == old) 663d09d8df3SJosef Bacik break; 664d09d8df3SJosef Bacik old = cur; 665d09d8df3SJosef Bacik } 666d09d8df3SJosef Bacik 667d09d8df3SJosef Bacik if (old == 0) 668d09d8df3SJosef Bacik return 0; 669d09d8df3SJosef Bacik if (old == 1) 670d09d8df3SJosef Bacik atomic_dec(&blkg->blkcg->css.cgroup->congestion_count); 671d09d8df3SJosef Bacik return 1; 672d09d8df3SJosef Bacik } 673d09d8df3SJosef Bacik 674d09d8df3SJosef Bacik static inline void blkcg_clear_delay(struct blkcg_gq *blkg) 675d09d8df3SJosef Bacik { 676d09d8df3SJosef Bacik int old = atomic_read(&blkg->use_delay); 677d09d8df3SJosef Bacik if (!old) 678d09d8df3SJosef Bacik return; 679d09d8df3SJosef Bacik /* We only want 1 person clearing the congestion count for this blkg. */ 680d09d8df3SJosef Bacik while (old) { 681d09d8df3SJosef Bacik int cur = atomic_cmpxchg(&blkg->use_delay, old, 0); 682d09d8df3SJosef Bacik if (cur == old) { 683d09d8df3SJosef Bacik atomic_dec(&blkg->blkcg->css.cgroup->congestion_count); 684d09d8df3SJosef Bacik break; 685d09d8df3SJosef Bacik } 686d09d8df3SJosef Bacik old = cur; 687d09d8df3SJosef Bacik } 688d09d8df3SJosef Bacik } 689d09d8df3SJosef Bacik 690d09d8df3SJosef Bacik void blkcg_add_delay(struct blkcg_gq *blkg, u64 now, u64 delta); 691d09d8df3SJosef Bacik void blkcg_schedule_throttle(struct request_queue *q, bool use_memdelay); 692d09d8df3SJosef Bacik void blkcg_maybe_throttle_current(void); 693eea8f41cSTejun Heo #else /* CONFIG_BLK_CGROUP */ 694eea8f41cSTejun Heo 695efa7d1c7STejun Heo struct blkcg { 696efa7d1c7STejun Heo }; 697eea8f41cSTejun Heo 698eea8f41cSTejun Heo struct blkg_policy_data { 699eea8f41cSTejun Heo }; 700eea8f41cSTejun Heo 701e4bc13adSLinus Torvalds struct blkcg_policy_data { 702e4bc13adSLinus Torvalds }; 703e4bc13adSLinus Torvalds 704eea8f41cSTejun Heo struct blkcg_gq { 705eea8f41cSTejun Heo }; 706eea8f41cSTejun Heo 707eea8f41cSTejun Heo struct blkcg_policy { 708eea8f41cSTejun Heo }; 709eea8f41cSTejun Heo 710496d5e75STejun Heo #define blkcg_root_css ((struct cgroup_subsys_state *)ERR_PTR(-EINVAL)) 711496d5e75STejun Heo 712d09d8df3SJosef Bacik static inline void blkcg_maybe_throttle_current(void) { } 713d09d8df3SJosef Bacik static inline bool blk_cgroup_congested(void) { return false; } 714d09d8df3SJosef Bacik 715efa7d1c7STejun Heo #ifdef CONFIG_BLOCK 716efa7d1c7STejun Heo 717d09d8df3SJosef Bacik static inline void blkcg_schedule_throttle(struct request_queue *q, bool use_memdelay) { } 718d09d8df3SJosef Bacik 719eea8f41cSTejun Heo static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; } 720b86d865cSBart Van Assche static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q) 721b86d865cSBart Van Assche { return NULL; } 722eea8f41cSTejun Heo static inline int blkcg_init_queue(struct request_queue *q) { return 0; } 723eea8f41cSTejun Heo static inline void blkcg_drain_queue(struct request_queue *q) { } 724eea8f41cSTejun Heo static inline void blkcg_exit_queue(struct request_queue *q) { } 725eea8f41cSTejun Heo static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; } 726eea8f41cSTejun Heo static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { } 727eea8f41cSTejun Heo static inline int blkcg_activate_policy(struct request_queue *q, 728eea8f41cSTejun Heo const struct blkcg_policy *pol) { return 0; } 729eea8f41cSTejun Heo static inline void blkcg_deactivate_policy(struct request_queue *q, 730eea8f41cSTejun Heo const struct blkcg_policy *pol) { } 731eea8f41cSTejun Heo 7320fe061b9SDennis Zhou static inline struct blkcg *__bio_blkcg(struct bio *bio) { return NULL; } 733eea8f41cSTejun Heo static inline struct blkcg *bio_blkcg(struct bio *bio) { return NULL; } 734eea8f41cSTejun Heo 735eea8f41cSTejun Heo static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg, 736eea8f41cSTejun Heo struct blkcg_policy *pol) { return NULL; } 737eea8f41cSTejun Heo static inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd) { return NULL; } 738eea8f41cSTejun Heo static inline char *blkg_path(struct blkcg_gq *blkg) { return NULL; } 739eea8f41cSTejun Heo static inline void blkg_get(struct blkcg_gq *blkg) { } 740eea8f41cSTejun Heo static inline void blkg_put(struct blkcg_gq *blkg) { } 741eea8f41cSTejun Heo 742d3f77dfdSTejun Heo static inline bool blkcg_punt_bio_submit(struct bio *bio) { return false; } 743e439bedfSDennis Zhou static inline void blkcg_bio_issue_init(struct bio *bio) { } 744ae118896STejun Heo static inline bool blkcg_bio_issue_check(struct request_queue *q, 745ae118896STejun Heo struct bio *bio) { return true; } 746ae118896STejun Heo 747eea8f41cSTejun Heo #define blk_queue_for_each_rl(rl, q) \ 748eea8f41cSTejun Heo for ((rl) = &(q)->root_rl; (rl); (rl) = NULL) 749eea8f41cSTejun Heo 750efa7d1c7STejun Heo #endif /* CONFIG_BLOCK */ 751eea8f41cSTejun Heo #endif /* CONFIG_BLK_CGROUP */ 752eea8f41cSTejun Heo #endif /* _BLK_CGROUP_H */ 753