1*eea8f41cSTejun Heo #ifndef _BLK_CGROUP_H 2*eea8f41cSTejun Heo #define _BLK_CGROUP_H 3*eea8f41cSTejun Heo /* 4*eea8f41cSTejun Heo * Common Block IO controller cgroup interface 5*eea8f41cSTejun Heo * 6*eea8f41cSTejun Heo * Based on ideas and code from CFQ, CFS and BFQ: 7*eea8f41cSTejun Heo * Copyright (C) 2003 Jens Axboe <[email protected]> 8*eea8f41cSTejun Heo * 9*eea8f41cSTejun Heo * Copyright (C) 2008 Fabio Checconi <[email protected]> 10*eea8f41cSTejun Heo * Paolo Valente <[email protected]> 11*eea8f41cSTejun Heo * 12*eea8f41cSTejun Heo * Copyright (C) 2009 Vivek Goyal <[email protected]> 13*eea8f41cSTejun Heo * Nauman Rafique <[email protected]> 14*eea8f41cSTejun Heo */ 15*eea8f41cSTejun Heo 16*eea8f41cSTejun Heo #include <linux/cgroup.h> 17*eea8f41cSTejun Heo #include <linux/u64_stats_sync.h> 18*eea8f41cSTejun Heo #include <linux/seq_file.h> 19*eea8f41cSTejun Heo #include <linux/radix-tree.h> 20*eea8f41cSTejun Heo #include <linux/blkdev.h> 21*eea8f41cSTejun Heo #include <linux/atomic.h> 22*eea8f41cSTejun Heo 23*eea8f41cSTejun Heo /* Max limits for throttle policy */ 24*eea8f41cSTejun Heo #define THROTL_IOPS_MAX UINT_MAX 25*eea8f41cSTejun Heo 26*eea8f41cSTejun Heo /* CFQ specific, out here for blkcg->cfq_weight */ 27*eea8f41cSTejun Heo #define CFQ_WEIGHT_MIN 10 28*eea8f41cSTejun Heo #define CFQ_WEIGHT_MAX 1000 29*eea8f41cSTejun Heo #define CFQ_WEIGHT_DEFAULT 500 30*eea8f41cSTejun Heo 31*eea8f41cSTejun Heo #ifdef CONFIG_BLK_CGROUP 32*eea8f41cSTejun Heo 33*eea8f41cSTejun Heo enum blkg_rwstat_type { 34*eea8f41cSTejun Heo BLKG_RWSTAT_READ, 35*eea8f41cSTejun Heo BLKG_RWSTAT_WRITE, 36*eea8f41cSTejun Heo BLKG_RWSTAT_SYNC, 37*eea8f41cSTejun Heo BLKG_RWSTAT_ASYNC, 38*eea8f41cSTejun Heo 39*eea8f41cSTejun Heo BLKG_RWSTAT_NR, 40*eea8f41cSTejun Heo BLKG_RWSTAT_TOTAL = BLKG_RWSTAT_NR, 41*eea8f41cSTejun Heo }; 42*eea8f41cSTejun Heo 43*eea8f41cSTejun Heo struct blkcg_gq; 44*eea8f41cSTejun Heo 45*eea8f41cSTejun Heo struct blkcg { 46*eea8f41cSTejun Heo struct cgroup_subsys_state css; 47*eea8f41cSTejun Heo spinlock_t lock; 48*eea8f41cSTejun Heo 49*eea8f41cSTejun Heo struct radix_tree_root blkg_tree; 50*eea8f41cSTejun Heo struct blkcg_gq *blkg_hint; 51*eea8f41cSTejun Heo struct hlist_head blkg_list; 52*eea8f41cSTejun Heo 53*eea8f41cSTejun Heo /* TODO: per-policy storage in blkcg */ 54*eea8f41cSTejun Heo unsigned int cfq_weight; /* belongs to cfq */ 55*eea8f41cSTejun Heo unsigned int cfq_leaf_weight; 56*eea8f41cSTejun Heo }; 57*eea8f41cSTejun Heo 58*eea8f41cSTejun Heo struct blkg_stat { 59*eea8f41cSTejun Heo struct u64_stats_sync syncp; 60*eea8f41cSTejun Heo uint64_t cnt; 61*eea8f41cSTejun Heo }; 62*eea8f41cSTejun Heo 63*eea8f41cSTejun Heo struct blkg_rwstat { 64*eea8f41cSTejun Heo struct u64_stats_sync syncp; 65*eea8f41cSTejun Heo uint64_t cnt[BLKG_RWSTAT_NR]; 66*eea8f41cSTejun Heo }; 67*eea8f41cSTejun Heo 68*eea8f41cSTejun Heo /* 69*eea8f41cSTejun Heo * A blkcg_gq (blkg) is association between a block cgroup (blkcg) and a 70*eea8f41cSTejun Heo * request_queue (q). This is used by blkcg policies which need to track 71*eea8f41cSTejun Heo * information per blkcg - q pair. 72*eea8f41cSTejun Heo * 73*eea8f41cSTejun Heo * There can be multiple active blkcg policies and each has its private 74*eea8f41cSTejun Heo * data on each blkg, the size of which is determined by 75*eea8f41cSTejun Heo * blkcg_policy->pd_size. blkcg core allocates and frees such areas 76*eea8f41cSTejun Heo * together with blkg and invokes pd_init/exit_fn() methods. 77*eea8f41cSTejun Heo * 78*eea8f41cSTejun Heo * Such private data must embed struct blkg_policy_data (pd) at the 79*eea8f41cSTejun Heo * beginning and pd_size can't be smaller than pd. 80*eea8f41cSTejun Heo */ 81*eea8f41cSTejun Heo struct blkg_policy_data { 82*eea8f41cSTejun Heo /* the blkg and policy id this per-policy data belongs to */ 83*eea8f41cSTejun Heo struct blkcg_gq *blkg; 84*eea8f41cSTejun Heo int plid; 85*eea8f41cSTejun Heo 86*eea8f41cSTejun Heo /* used during policy activation */ 87*eea8f41cSTejun Heo struct list_head alloc_node; 88*eea8f41cSTejun Heo }; 89*eea8f41cSTejun Heo 90*eea8f41cSTejun Heo /* association between a blk cgroup and a request queue */ 91*eea8f41cSTejun Heo struct blkcg_gq { 92*eea8f41cSTejun Heo /* Pointer to the associated request_queue */ 93*eea8f41cSTejun Heo struct request_queue *q; 94*eea8f41cSTejun Heo struct list_head q_node; 95*eea8f41cSTejun Heo struct hlist_node blkcg_node; 96*eea8f41cSTejun Heo struct blkcg *blkcg; 97*eea8f41cSTejun Heo 98*eea8f41cSTejun Heo /* all non-root blkcg_gq's are guaranteed to have access to parent */ 99*eea8f41cSTejun Heo struct blkcg_gq *parent; 100*eea8f41cSTejun Heo 101*eea8f41cSTejun Heo /* request allocation list for this blkcg-q pair */ 102*eea8f41cSTejun Heo struct request_list rl; 103*eea8f41cSTejun Heo 104*eea8f41cSTejun Heo /* reference count */ 105*eea8f41cSTejun Heo atomic_t refcnt; 106*eea8f41cSTejun Heo 107*eea8f41cSTejun Heo /* is this blkg online? protected by both blkcg and q locks */ 108*eea8f41cSTejun Heo bool online; 109*eea8f41cSTejun Heo 110*eea8f41cSTejun Heo struct blkg_policy_data *pd[BLKCG_MAX_POLS]; 111*eea8f41cSTejun Heo 112*eea8f41cSTejun Heo struct rcu_head rcu_head; 113*eea8f41cSTejun Heo }; 114*eea8f41cSTejun Heo 115*eea8f41cSTejun Heo typedef void (blkcg_pol_init_pd_fn)(struct blkcg_gq *blkg); 116*eea8f41cSTejun Heo typedef void (blkcg_pol_online_pd_fn)(struct blkcg_gq *blkg); 117*eea8f41cSTejun Heo typedef void (blkcg_pol_offline_pd_fn)(struct blkcg_gq *blkg); 118*eea8f41cSTejun Heo typedef void (blkcg_pol_exit_pd_fn)(struct blkcg_gq *blkg); 119*eea8f41cSTejun Heo typedef void (blkcg_pol_reset_pd_stats_fn)(struct blkcg_gq *blkg); 120*eea8f41cSTejun Heo 121*eea8f41cSTejun Heo struct blkcg_policy { 122*eea8f41cSTejun Heo int plid; 123*eea8f41cSTejun Heo /* policy specific private data size */ 124*eea8f41cSTejun Heo size_t pd_size; 125*eea8f41cSTejun Heo /* cgroup files for the policy */ 126*eea8f41cSTejun Heo struct cftype *cftypes; 127*eea8f41cSTejun Heo 128*eea8f41cSTejun Heo /* operations */ 129*eea8f41cSTejun Heo blkcg_pol_init_pd_fn *pd_init_fn; 130*eea8f41cSTejun Heo blkcg_pol_online_pd_fn *pd_online_fn; 131*eea8f41cSTejun Heo blkcg_pol_offline_pd_fn *pd_offline_fn; 132*eea8f41cSTejun Heo blkcg_pol_exit_pd_fn *pd_exit_fn; 133*eea8f41cSTejun Heo blkcg_pol_reset_pd_stats_fn *pd_reset_stats_fn; 134*eea8f41cSTejun Heo }; 135*eea8f41cSTejun Heo 136*eea8f41cSTejun Heo extern struct blkcg blkcg_root; 137*eea8f41cSTejun Heo 138*eea8f41cSTejun Heo struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, struct request_queue *q); 139*eea8f41cSTejun Heo struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg, 140*eea8f41cSTejun Heo struct request_queue *q); 141*eea8f41cSTejun Heo int blkcg_init_queue(struct request_queue *q); 142*eea8f41cSTejun Heo void blkcg_drain_queue(struct request_queue *q); 143*eea8f41cSTejun Heo void blkcg_exit_queue(struct request_queue *q); 144*eea8f41cSTejun Heo 145*eea8f41cSTejun Heo /* Blkio controller policy registration */ 146*eea8f41cSTejun Heo int blkcg_policy_register(struct blkcg_policy *pol); 147*eea8f41cSTejun Heo void blkcg_policy_unregister(struct blkcg_policy *pol); 148*eea8f41cSTejun Heo int blkcg_activate_policy(struct request_queue *q, 149*eea8f41cSTejun Heo const struct blkcg_policy *pol); 150*eea8f41cSTejun Heo void blkcg_deactivate_policy(struct request_queue *q, 151*eea8f41cSTejun Heo const struct blkcg_policy *pol); 152*eea8f41cSTejun Heo 153*eea8f41cSTejun Heo void blkcg_print_blkgs(struct seq_file *sf, struct blkcg *blkcg, 154*eea8f41cSTejun Heo u64 (*prfill)(struct seq_file *, 155*eea8f41cSTejun Heo struct blkg_policy_data *, int), 156*eea8f41cSTejun Heo const struct blkcg_policy *pol, int data, 157*eea8f41cSTejun Heo bool show_total); 158*eea8f41cSTejun Heo u64 __blkg_prfill_u64(struct seq_file *sf, struct blkg_policy_data *pd, u64 v); 159*eea8f41cSTejun Heo u64 __blkg_prfill_rwstat(struct seq_file *sf, struct blkg_policy_data *pd, 160*eea8f41cSTejun Heo const struct blkg_rwstat *rwstat); 161*eea8f41cSTejun Heo u64 blkg_prfill_stat(struct seq_file *sf, struct blkg_policy_data *pd, int off); 162*eea8f41cSTejun Heo u64 blkg_prfill_rwstat(struct seq_file *sf, struct blkg_policy_data *pd, 163*eea8f41cSTejun Heo int off); 164*eea8f41cSTejun Heo 165*eea8f41cSTejun Heo u64 blkg_stat_recursive_sum(struct blkg_policy_data *pd, int off); 166*eea8f41cSTejun Heo struct blkg_rwstat blkg_rwstat_recursive_sum(struct blkg_policy_data *pd, 167*eea8f41cSTejun Heo int off); 168*eea8f41cSTejun Heo 169*eea8f41cSTejun Heo struct blkg_conf_ctx { 170*eea8f41cSTejun Heo struct gendisk *disk; 171*eea8f41cSTejun Heo struct blkcg_gq *blkg; 172*eea8f41cSTejun Heo u64 v; 173*eea8f41cSTejun Heo }; 174*eea8f41cSTejun Heo 175*eea8f41cSTejun Heo int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, 176*eea8f41cSTejun Heo const char *input, struct blkg_conf_ctx *ctx); 177*eea8f41cSTejun Heo void blkg_conf_finish(struct blkg_conf_ctx *ctx); 178*eea8f41cSTejun Heo 179*eea8f41cSTejun Heo 180*eea8f41cSTejun Heo static inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *css) 181*eea8f41cSTejun Heo { 182*eea8f41cSTejun Heo return css ? container_of(css, struct blkcg, css) : NULL; 183*eea8f41cSTejun Heo } 184*eea8f41cSTejun Heo 185*eea8f41cSTejun Heo static inline struct blkcg *task_blkcg(struct task_struct *tsk) 186*eea8f41cSTejun Heo { 187*eea8f41cSTejun Heo return css_to_blkcg(task_css(tsk, blkio_cgrp_id)); 188*eea8f41cSTejun Heo } 189*eea8f41cSTejun Heo 190*eea8f41cSTejun Heo static inline struct blkcg *bio_blkcg(struct bio *bio) 191*eea8f41cSTejun Heo { 192*eea8f41cSTejun Heo if (bio && bio->bi_css) 193*eea8f41cSTejun Heo return css_to_blkcg(bio->bi_css); 194*eea8f41cSTejun Heo return task_blkcg(current); 195*eea8f41cSTejun Heo } 196*eea8f41cSTejun Heo 197*eea8f41cSTejun Heo /** 198*eea8f41cSTejun Heo * blkcg_parent - get the parent of a blkcg 199*eea8f41cSTejun Heo * @blkcg: blkcg of interest 200*eea8f41cSTejun Heo * 201*eea8f41cSTejun Heo * Return the parent blkcg of @blkcg. Can be called anytime. 202*eea8f41cSTejun Heo */ 203*eea8f41cSTejun Heo static inline struct blkcg *blkcg_parent(struct blkcg *blkcg) 204*eea8f41cSTejun Heo { 205*eea8f41cSTejun Heo return css_to_blkcg(blkcg->css.parent); 206*eea8f41cSTejun Heo } 207*eea8f41cSTejun Heo 208*eea8f41cSTejun Heo /** 209*eea8f41cSTejun Heo * blkg_to_pdata - get policy private data 210*eea8f41cSTejun Heo * @blkg: blkg of interest 211*eea8f41cSTejun Heo * @pol: policy of interest 212*eea8f41cSTejun Heo * 213*eea8f41cSTejun Heo * Return pointer to private data associated with the @blkg-@pol pair. 214*eea8f41cSTejun Heo */ 215*eea8f41cSTejun Heo static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg, 216*eea8f41cSTejun Heo struct blkcg_policy *pol) 217*eea8f41cSTejun Heo { 218*eea8f41cSTejun Heo return blkg ? blkg->pd[pol->plid] : NULL; 219*eea8f41cSTejun Heo } 220*eea8f41cSTejun Heo 221*eea8f41cSTejun Heo /** 222*eea8f41cSTejun Heo * pdata_to_blkg - get blkg associated with policy private data 223*eea8f41cSTejun Heo * @pd: policy private data of interest 224*eea8f41cSTejun Heo * 225*eea8f41cSTejun Heo * @pd is policy private data. Determine the blkg it's associated with. 226*eea8f41cSTejun Heo */ 227*eea8f41cSTejun Heo static inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd) 228*eea8f41cSTejun Heo { 229*eea8f41cSTejun Heo return pd ? pd->blkg : NULL; 230*eea8f41cSTejun Heo } 231*eea8f41cSTejun Heo 232*eea8f41cSTejun Heo /** 233*eea8f41cSTejun Heo * blkg_path - format cgroup path of blkg 234*eea8f41cSTejun Heo * @blkg: blkg of interest 235*eea8f41cSTejun Heo * @buf: target buffer 236*eea8f41cSTejun Heo * @buflen: target buffer length 237*eea8f41cSTejun Heo * 238*eea8f41cSTejun Heo * Format the path of the cgroup of @blkg into @buf. 239*eea8f41cSTejun Heo */ 240*eea8f41cSTejun Heo static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen) 241*eea8f41cSTejun Heo { 242*eea8f41cSTejun Heo char *p; 243*eea8f41cSTejun Heo 244*eea8f41cSTejun Heo p = cgroup_path(blkg->blkcg->css.cgroup, buf, buflen); 245*eea8f41cSTejun Heo if (!p) { 246*eea8f41cSTejun Heo strncpy(buf, "<unavailable>", buflen); 247*eea8f41cSTejun Heo return -ENAMETOOLONG; 248*eea8f41cSTejun Heo } 249*eea8f41cSTejun Heo 250*eea8f41cSTejun Heo memmove(buf, p, buf + buflen - p); 251*eea8f41cSTejun Heo return 0; 252*eea8f41cSTejun Heo } 253*eea8f41cSTejun Heo 254*eea8f41cSTejun Heo /** 255*eea8f41cSTejun Heo * blkg_get - get a blkg reference 256*eea8f41cSTejun Heo * @blkg: blkg to get 257*eea8f41cSTejun Heo * 258*eea8f41cSTejun Heo * The caller should be holding an existing reference. 259*eea8f41cSTejun Heo */ 260*eea8f41cSTejun Heo static inline void blkg_get(struct blkcg_gq *blkg) 261*eea8f41cSTejun Heo { 262*eea8f41cSTejun Heo WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0); 263*eea8f41cSTejun Heo atomic_inc(&blkg->refcnt); 264*eea8f41cSTejun Heo } 265*eea8f41cSTejun Heo 266*eea8f41cSTejun Heo void __blkg_release_rcu(struct rcu_head *rcu); 267*eea8f41cSTejun Heo 268*eea8f41cSTejun Heo /** 269*eea8f41cSTejun Heo * blkg_put - put a blkg reference 270*eea8f41cSTejun Heo * @blkg: blkg to put 271*eea8f41cSTejun Heo */ 272*eea8f41cSTejun Heo static inline void blkg_put(struct blkcg_gq *blkg) 273*eea8f41cSTejun Heo { 274*eea8f41cSTejun Heo WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0); 275*eea8f41cSTejun Heo if (atomic_dec_and_test(&blkg->refcnt)) 276*eea8f41cSTejun Heo call_rcu(&blkg->rcu_head, __blkg_release_rcu); 277*eea8f41cSTejun Heo } 278*eea8f41cSTejun Heo 279*eea8f41cSTejun Heo struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg, struct request_queue *q, 280*eea8f41cSTejun Heo bool update_hint); 281*eea8f41cSTejun Heo 282*eea8f41cSTejun Heo /** 283*eea8f41cSTejun Heo * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants 284*eea8f41cSTejun Heo * @d_blkg: loop cursor pointing to the current descendant 285*eea8f41cSTejun Heo * @pos_css: used for iteration 286*eea8f41cSTejun Heo * @p_blkg: target blkg to walk descendants of 287*eea8f41cSTejun Heo * 288*eea8f41cSTejun Heo * Walk @c_blkg through the descendants of @p_blkg. Must be used with RCU 289*eea8f41cSTejun Heo * read locked. If called under either blkcg or queue lock, the iteration 290*eea8f41cSTejun Heo * is guaranteed to include all and only online blkgs. The caller may 291*eea8f41cSTejun Heo * update @pos_css by calling css_rightmost_descendant() to skip subtree. 292*eea8f41cSTejun Heo * @p_blkg is included in the iteration and the first node to be visited. 293*eea8f41cSTejun Heo */ 294*eea8f41cSTejun Heo #define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg) \ 295*eea8f41cSTejun Heo css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css) \ 296*eea8f41cSTejun Heo if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \ 297*eea8f41cSTejun Heo (p_blkg)->q, false))) 298*eea8f41cSTejun Heo 299*eea8f41cSTejun Heo /** 300*eea8f41cSTejun Heo * blkg_for_each_descendant_post - post-order walk of a blkg's descendants 301*eea8f41cSTejun Heo * @d_blkg: loop cursor pointing to the current descendant 302*eea8f41cSTejun Heo * @pos_css: used for iteration 303*eea8f41cSTejun Heo * @p_blkg: target blkg to walk descendants of 304*eea8f41cSTejun Heo * 305*eea8f41cSTejun Heo * Similar to blkg_for_each_descendant_pre() but performs post-order 306*eea8f41cSTejun Heo * traversal instead. Synchronization rules are the same. @p_blkg is 307*eea8f41cSTejun Heo * included in the iteration and the last node to be visited. 308*eea8f41cSTejun Heo */ 309*eea8f41cSTejun Heo #define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg) \ 310*eea8f41cSTejun Heo css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css) \ 311*eea8f41cSTejun Heo if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css), \ 312*eea8f41cSTejun Heo (p_blkg)->q, false))) 313*eea8f41cSTejun Heo 314*eea8f41cSTejun Heo /** 315*eea8f41cSTejun Heo * blk_get_rl - get request_list to use 316*eea8f41cSTejun Heo * @q: request_queue of interest 317*eea8f41cSTejun Heo * @bio: bio which will be attached to the allocated request (may be %NULL) 318*eea8f41cSTejun Heo * 319*eea8f41cSTejun Heo * The caller wants to allocate a request from @q to use for @bio. Find 320*eea8f41cSTejun Heo * the request_list to use and obtain a reference on it. Should be called 321*eea8f41cSTejun Heo * under queue_lock. This function is guaranteed to return non-%NULL 322*eea8f41cSTejun Heo * request_list. 323*eea8f41cSTejun Heo */ 324*eea8f41cSTejun Heo static inline struct request_list *blk_get_rl(struct request_queue *q, 325*eea8f41cSTejun Heo struct bio *bio) 326*eea8f41cSTejun Heo { 327*eea8f41cSTejun Heo struct blkcg *blkcg; 328*eea8f41cSTejun Heo struct blkcg_gq *blkg; 329*eea8f41cSTejun Heo 330*eea8f41cSTejun Heo rcu_read_lock(); 331*eea8f41cSTejun Heo 332*eea8f41cSTejun Heo blkcg = bio_blkcg(bio); 333*eea8f41cSTejun Heo 334*eea8f41cSTejun Heo /* bypass blkg lookup and use @q->root_rl directly for root */ 335*eea8f41cSTejun Heo if (blkcg == &blkcg_root) 336*eea8f41cSTejun Heo goto root_rl; 337*eea8f41cSTejun Heo 338*eea8f41cSTejun Heo /* 339*eea8f41cSTejun Heo * Try to use blkg->rl. blkg lookup may fail under memory pressure 340*eea8f41cSTejun Heo * or if either the blkcg or queue is going away. Fall back to 341*eea8f41cSTejun Heo * root_rl in such cases. 342*eea8f41cSTejun Heo */ 343*eea8f41cSTejun Heo blkg = blkg_lookup_create(blkcg, q); 344*eea8f41cSTejun Heo if (unlikely(IS_ERR(blkg))) 345*eea8f41cSTejun Heo goto root_rl; 346*eea8f41cSTejun Heo 347*eea8f41cSTejun Heo blkg_get(blkg); 348*eea8f41cSTejun Heo rcu_read_unlock(); 349*eea8f41cSTejun Heo return &blkg->rl; 350*eea8f41cSTejun Heo root_rl: 351*eea8f41cSTejun Heo rcu_read_unlock(); 352*eea8f41cSTejun Heo return &q->root_rl; 353*eea8f41cSTejun Heo } 354*eea8f41cSTejun Heo 355*eea8f41cSTejun Heo /** 356*eea8f41cSTejun Heo * blk_put_rl - put request_list 357*eea8f41cSTejun Heo * @rl: request_list to put 358*eea8f41cSTejun Heo * 359*eea8f41cSTejun Heo * Put the reference acquired by blk_get_rl(). Should be called under 360*eea8f41cSTejun Heo * queue_lock. 361*eea8f41cSTejun Heo */ 362*eea8f41cSTejun Heo static inline void blk_put_rl(struct request_list *rl) 363*eea8f41cSTejun Heo { 364*eea8f41cSTejun Heo /* root_rl may not have blkg set */ 365*eea8f41cSTejun Heo if (rl->blkg && rl->blkg->blkcg != &blkcg_root) 366*eea8f41cSTejun Heo blkg_put(rl->blkg); 367*eea8f41cSTejun Heo } 368*eea8f41cSTejun Heo 369*eea8f41cSTejun Heo /** 370*eea8f41cSTejun Heo * blk_rq_set_rl - associate a request with a request_list 371*eea8f41cSTejun Heo * @rq: request of interest 372*eea8f41cSTejun Heo * @rl: target request_list 373*eea8f41cSTejun Heo * 374*eea8f41cSTejun Heo * Associate @rq with @rl so that accounting and freeing can know the 375*eea8f41cSTejun Heo * request_list @rq came from. 376*eea8f41cSTejun Heo */ 377*eea8f41cSTejun Heo static inline void blk_rq_set_rl(struct request *rq, struct request_list *rl) 378*eea8f41cSTejun Heo { 379*eea8f41cSTejun Heo rq->rl = rl; 380*eea8f41cSTejun Heo } 381*eea8f41cSTejun Heo 382*eea8f41cSTejun Heo /** 383*eea8f41cSTejun Heo * blk_rq_rl - return the request_list a request came from 384*eea8f41cSTejun Heo * @rq: request of interest 385*eea8f41cSTejun Heo * 386*eea8f41cSTejun Heo * Return the request_list @rq is allocated from. 387*eea8f41cSTejun Heo */ 388*eea8f41cSTejun Heo static inline struct request_list *blk_rq_rl(struct request *rq) 389*eea8f41cSTejun Heo { 390*eea8f41cSTejun Heo return rq->rl; 391*eea8f41cSTejun Heo } 392*eea8f41cSTejun Heo 393*eea8f41cSTejun Heo struct request_list *__blk_queue_next_rl(struct request_list *rl, 394*eea8f41cSTejun Heo struct request_queue *q); 395*eea8f41cSTejun Heo /** 396*eea8f41cSTejun Heo * blk_queue_for_each_rl - iterate through all request_lists of a request_queue 397*eea8f41cSTejun Heo * 398*eea8f41cSTejun Heo * Should be used under queue_lock. 399*eea8f41cSTejun Heo */ 400*eea8f41cSTejun Heo #define blk_queue_for_each_rl(rl, q) \ 401*eea8f41cSTejun Heo for ((rl) = &(q)->root_rl; (rl); (rl) = __blk_queue_next_rl((rl), (q))) 402*eea8f41cSTejun Heo 403*eea8f41cSTejun Heo static inline void blkg_stat_init(struct blkg_stat *stat) 404*eea8f41cSTejun Heo { 405*eea8f41cSTejun Heo u64_stats_init(&stat->syncp); 406*eea8f41cSTejun Heo } 407*eea8f41cSTejun Heo 408*eea8f41cSTejun Heo /** 409*eea8f41cSTejun Heo * blkg_stat_add - add a value to a blkg_stat 410*eea8f41cSTejun Heo * @stat: target blkg_stat 411*eea8f41cSTejun Heo * @val: value to add 412*eea8f41cSTejun Heo * 413*eea8f41cSTejun Heo * Add @val to @stat. The caller is responsible for synchronizing calls to 414*eea8f41cSTejun Heo * this function. 415*eea8f41cSTejun Heo */ 416*eea8f41cSTejun Heo static inline void blkg_stat_add(struct blkg_stat *stat, uint64_t val) 417*eea8f41cSTejun Heo { 418*eea8f41cSTejun Heo u64_stats_update_begin(&stat->syncp); 419*eea8f41cSTejun Heo stat->cnt += val; 420*eea8f41cSTejun Heo u64_stats_update_end(&stat->syncp); 421*eea8f41cSTejun Heo } 422*eea8f41cSTejun Heo 423*eea8f41cSTejun Heo /** 424*eea8f41cSTejun Heo * blkg_stat_read - read the current value of a blkg_stat 425*eea8f41cSTejun Heo * @stat: blkg_stat to read 426*eea8f41cSTejun Heo * 427*eea8f41cSTejun Heo * Read the current value of @stat. This function can be called without 428*eea8f41cSTejun Heo * synchroniztion and takes care of u64 atomicity. 429*eea8f41cSTejun Heo */ 430*eea8f41cSTejun Heo static inline uint64_t blkg_stat_read(struct blkg_stat *stat) 431*eea8f41cSTejun Heo { 432*eea8f41cSTejun Heo unsigned int start; 433*eea8f41cSTejun Heo uint64_t v; 434*eea8f41cSTejun Heo 435*eea8f41cSTejun Heo do { 436*eea8f41cSTejun Heo start = u64_stats_fetch_begin_irq(&stat->syncp); 437*eea8f41cSTejun Heo v = stat->cnt; 438*eea8f41cSTejun Heo } while (u64_stats_fetch_retry_irq(&stat->syncp, start)); 439*eea8f41cSTejun Heo 440*eea8f41cSTejun Heo return v; 441*eea8f41cSTejun Heo } 442*eea8f41cSTejun Heo 443*eea8f41cSTejun Heo /** 444*eea8f41cSTejun Heo * blkg_stat_reset - reset a blkg_stat 445*eea8f41cSTejun Heo * @stat: blkg_stat to reset 446*eea8f41cSTejun Heo */ 447*eea8f41cSTejun Heo static inline void blkg_stat_reset(struct blkg_stat *stat) 448*eea8f41cSTejun Heo { 449*eea8f41cSTejun Heo stat->cnt = 0; 450*eea8f41cSTejun Heo } 451*eea8f41cSTejun Heo 452*eea8f41cSTejun Heo /** 453*eea8f41cSTejun Heo * blkg_stat_merge - merge a blkg_stat into another 454*eea8f41cSTejun Heo * @to: the destination blkg_stat 455*eea8f41cSTejun Heo * @from: the source 456*eea8f41cSTejun Heo * 457*eea8f41cSTejun Heo * Add @from's count to @to. 458*eea8f41cSTejun Heo */ 459*eea8f41cSTejun Heo static inline void blkg_stat_merge(struct blkg_stat *to, struct blkg_stat *from) 460*eea8f41cSTejun Heo { 461*eea8f41cSTejun Heo blkg_stat_add(to, blkg_stat_read(from)); 462*eea8f41cSTejun Heo } 463*eea8f41cSTejun Heo 464*eea8f41cSTejun Heo static inline void blkg_rwstat_init(struct blkg_rwstat *rwstat) 465*eea8f41cSTejun Heo { 466*eea8f41cSTejun Heo u64_stats_init(&rwstat->syncp); 467*eea8f41cSTejun Heo } 468*eea8f41cSTejun Heo 469*eea8f41cSTejun Heo /** 470*eea8f41cSTejun Heo * blkg_rwstat_add - add a value to a blkg_rwstat 471*eea8f41cSTejun Heo * @rwstat: target blkg_rwstat 472*eea8f41cSTejun Heo * @rw: mask of REQ_{WRITE|SYNC} 473*eea8f41cSTejun Heo * @val: value to add 474*eea8f41cSTejun Heo * 475*eea8f41cSTejun Heo * Add @val to @rwstat. The counters are chosen according to @rw. The 476*eea8f41cSTejun Heo * caller is responsible for synchronizing calls to this function. 477*eea8f41cSTejun Heo */ 478*eea8f41cSTejun Heo static inline void blkg_rwstat_add(struct blkg_rwstat *rwstat, 479*eea8f41cSTejun Heo int rw, uint64_t val) 480*eea8f41cSTejun Heo { 481*eea8f41cSTejun Heo u64_stats_update_begin(&rwstat->syncp); 482*eea8f41cSTejun Heo 483*eea8f41cSTejun Heo if (rw & REQ_WRITE) 484*eea8f41cSTejun Heo rwstat->cnt[BLKG_RWSTAT_WRITE] += val; 485*eea8f41cSTejun Heo else 486*eea8f41cSTejun Heo rwstat->cnt[BLKG_RWSTAT_READ] += val; 487*eea8f41cSTejun Heo if (rw & REQ_SYNC) 488*eea8f41cSTejun Heo rwstat->cnt[BLKG_RWSTAT_SYNC] += val; 489*eea8f41cSTejun Heo else 490*eea8f41cSTejun Heo rwstat->cnt[BLKG_RWSTAT_ASYNC] += val; 491*eea8f41cSTejun Heo 492*eea8f41cSTejun Heo u64_stats_update_end(&rwstat->syncp); 493*eea8f41cSTejun Heo } 494*eea8f41cSTejun Heo 495*eea8f41cSTejun Heo /** 496*eea8f41cSTejun Heo * blkg_rwstat_read - read the current values of a blkg_rwstat 497*eea8f41cSTejun Heo * @rwstat: blkg_rwstat to read 498*eea8f41cSTejun Heo * 499*eea8f41cSTejun Heo * Read the current snapshot of @rwstat and return it as the return value. 500*eea8f41cSTejun Heo * This function can be called without synchronization and takes care of 501*eea8f41cSTejun Heo * u64 atomicity. 502*eea8f41cSTejun Heo */ 503*eea8f41cSTejun Heo static inline struct blkg_rwstat blkg_rwstat_read(struct blkg_rwstat *rwstat) 504*eea8f41cSTejun Heo { 505*eea8f41cSTejun Heo unsigned int start; 506*eea8f41cSTejun Heo struct blkg_rwstat tmp; 507*eea8f41cSTejun Heo 508*eea8f41cSTejun Heo do { 509*eea8f41cSTejun Heo start = u64_stats_fetch_begin_irq(&rwstat->syncp); 510*eea8f41cSTejun Heo tmp = *rwstat; 511*eea8f41cSTejun Heo } while (u64_stats_fetch_retry_irq(&rwstat->syncp, start)); 512*eea8f41cSTejun Heo 513*eea8f41cSTejun Heo return tmp; 514*eea8f41cSTejun Heo } 515*eea8f41cSTejun Heo 516*eea8f41cSTejun Heo /** 517*eea8f41cSTejun Heo * blkg_rwstat_total - read the total count of a blkg_rwstat 518*eea8f41cSTejun Heo * @rwstat: blkg_rwstat to read 519*eea8f41cSTejun Heo * 520*eea8f41cSTejun Heo * Return the total count of @rwstat regardless of the IO direction. This 521*eea8f41cSTejun Heo * function can be called without synchronization and takes care of u64 522*eea8f41cSTejun Heo * atomicity. 523*eea8f41cSTejun Heo */ 524*eea8f41cSTejun Heo static inline uint64_t blkg_rwstat_total(struct blkg_rwstat *rwstat) 525*eea8f41cSTejun Heo { 526*eea8f41cSTejun Heo struct blkg_rwstat tmp = blkg_rwstat_read(rwstat); 527*eea8f41cSTejun Heo 528*eea8f41cSTejun Heo return tmp.cnt[BLKG_RWSTAT_READ] + tmp.cnt[BLKG_RWSTAT_WRITE]; 529*eea8f41cSTejun Heo } 530*eea8f41cSTejun Heo 531*eea8f41cSTejun Heo /** 532*eea8f41cSTejun Heo * blkg_rwstat_reset - reset a blkg_rwstat 533*eea8f41cSTejun Heo * @rwstat: blkg_rwstat to reset 534*eea8f41cSTejun Heo */ 535*eea8f41cSTejun Heo static inline void blkg_rwstat_reset(struct blkg_rwstat *rwstat) 536*eea8f41cSTejun Heo { 537*eea8f41cSTejun Heo memset(rwstat->cnt, 0, sizeof(rwstat->cnt)); 538*eea8f41cSTejun Heo } 539*eea8f41cSTejun Heo 540*eea8f41cSTejun Heo /** 541*eea8f41cSTejun Heo * blkg_rwstat_merge - merge a blkg_rwstat into another 542*eea8f41cSTejun Heo * @to: the destination blkg_rwstat 543*eea8f41cSTejun Heo * @from: the source 544*eea8f41cSTejun Heo * 545*eea8f41cSTejun Heo * Add @from's counts to @to. 546*eea8f41cSTejun Heo */ 547*eea8f41cSTejun Heo static inline void blkg_rwstat_merge(struct blkg_rwstat *to, 548*eea8f41cSTejun Heo struct blkg_rwstat *from) 549*eea8f41cSTejun Heo { 550*eea8f41cSTejun Heo struct blkg_rwstat v = blkg_rwstat_read(from); 551*eea8f41cSTejun Heo int i; 552*eea8f41cSTejun Heo 553*eea8f41cSTejun Heo u64_stats_update_begin(&to->syncp); 554*eea8f41cSTejun Heo for (i = 0; i < BLKG_RWSTAT_NR; i++) 555*eea8f41cSTejun Heo to->cnt[i] += v.cnt[i]; 556*eea8f41cSTejun Heo u64_stats_update_end(&to->syncp); 557*eea8f41cSTejun Heo } 558*eea8f41cSTejun Heo 559*eea8f41cSTejun Heo #else /* CONFIG_BLK_CGROUP */ 560*eea8f41cSTejun Heo 561*eea8f41cSTejun Heo struct cgroup; 562*eea8f41cSTejun Heo struct blkcg; 563*eea8f41cSTejun Heo 564*eea8f41cSTejun Heo struct blkg_policy_data { 565*eea8f41cSTejun Heo }; 566*eea8f41cSTejun Heo 567*eea8f41cSTejun Heo struct blkcg_gq { 568*eea8f41cSTejun Heo }; 569*eea8f41cSTejun Heo 570*eea8f41cSTejun Heo struct blkcg_policy { 571*eea8f41cSTejun Heo }; 572*eea8f41cSTejun Heo 573*eea8f41cSTejun Heo static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; } 574*eea8f41cSTejun Heo static inline int blkcg_init_queue(struct request_queue *q) { return 0; } 575*eea8f41cSTejun Heo static inline void blkcg_drain_queue(struct request_queue *q) { } 576*eea8f41cSTejun Heo static inline void blkcg_exit_queue(struct request_queue *q) { } 577*eea8f41cSTejun Heo static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; } 578*eea8f41cSTejun Heo static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { } 579*eea8f41cSTejun Heo static inline int blkcg_activate_policy(struct request_queue *q, 580*eea8f41cSTejun Heo const struct blkcg_policy *pol) { return 0; } 581*eea8f41cSTejun Heo static inline void blkcg_deactivate_policy(struct request_queue *q, 582*eea8f41cSTejun Heo const struct blkcg_policy *pol) { } 583*eea8f41cSTejun Heo 584*eea8f41cSTejun Heo static inline struct blkcg *bio_blkcg(struct bio *bio) { return NULL; } 585*eea8f41cSTejun Heo 586*eea8f41cSTejun Heo static inline struct blkg_policy_data *blkg_to_pd(struct blkcg_gq *blkg, 587*eea8f41cSTejun Heo struct blkcg_policy *pol) { return NULL; } 588*eea8f41cSTejun Heo static inline struct blkcg_gq *pd_to_blkg(struct blkg_policy_data *pd) { return NULL; } 589*eea8f41cSTejun Heo static inline char *blkg_path(struct blkcg_gq *blkg) { return NULL; } 590*eea8f41cSTejun Heo static inline void blkg_get(struct blkcg_gq *blkg) { } 591*eea8f41cSTejun Heo static inline void blkg_put(struct blkcg_gq *blkg) { } 592*eea8f41cSTejun Heo 593*eea8f41cSTejun Heo static inline struct request_list *blk_get_rl(struct request_queue *q, 594*eea8f41cSTejun Heo struct bio *bio) { return &q->root_rl; } 595*eea8f41cSTejun Heo static inline void blk_put_rl(struct request_list *rl) { } 596*eea8f41cSTejun Heo static inline void blk_rq_set_rl(struct request *rq, struct request_list *rl) { } 597*eea8f41cSTejun Heo static inline struct request_list *blk_rq_rl(struct request *rq) { return &rq->q->root_rl; } 598*eea8f41cSTejun Heo 599*eea8f41cSTejun Heo #define blk_queue_for_each_rl(rl, q) \ 600*eea8f41cSTejun Heo for ((rl) = &(q)->root_rl; (rl); (rl) = NULL) 601*eea8f41cSTejun Heo 602*eea8f41cSTejun Heo #endif /* CONFIG_BLK_CGROUP */ 603*eea8f41cSTejun Heo #endif /* _BLK_CGROUP_H */ 604