1 #ifndef _BLK_CGROUP_H 2 #define _BLK_CGROUP_H 3 /* 4 * Common Block IO controller cgroup interface 5 * 6 * Based on ideas and code from CFQ, CFS and BFQ: 7 * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk> 8 * 9 * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it> 10 * Paolo Valente <paolo.valente@unimore.it> 11 * 12 * Copyright (C) 2009 Vivek Goyal <vgoyal@redhat.com> 13 * Nauman Rafique <nauman@google.com> 14 */ 15 16 #include <linux/cgroup.h> 17 18 enum blkio_policy_id { 19 BLKIO_POLICY_PROP = 0, /* Proportional Bandwidth division */ 20 BLKIO_POLICY_THROTL, /* Throttling */ 21 }; 22 23 /* Max limits for throttle policy */ 24 #define THROTL_IOPS_MAX UINT_MAX 25 26 #if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE) 27 28 #ifndef CONFIG_BLK_CGROUP 29 /* When blk-cgroup is a module, its subsys_id isn't a compile-time constant */ 30 extern struct cgroup_subsys blkio_subsys; 31 #define blkio_subsys_id blkio_subsys.subsys_id 32 #endif 33 34 enum stat_type { 35 /* Total time spent (in ns) between request dispatch to the driver and 36 * request completion for IOs doen by this cgroup. This may not be 37 * accurate when NCQ is turned on. */ 38 BLKIO_STAT_SERVICE_TIME = 0, 39 /* Total bytes transferred */ 40 BLKIO_STAT_SERVICE_BYTES, 41 /* Total IOs serviced, post merge */ 42 BLKIO_STAT_SERVICED, 43 /* Total time spent waiting in scheduler queue in ns */ 44 BLKIO_STAT_WAIT_TIME, 45 /* Number of IOs merged */ 46 BLKIO_STAT_MERGED, 47 /* Number of IOs queued up */ 48 BLKIO_STAT_QUEUED, 49 /* All the single valued stats go below this */ 50 BLKIO_STAT_TIME, 51 BLKIO_STAT_SECTORS, 52 /* Time not charged to this cgroup */ 53 BLKIO_STAT_UNACCOUNTED_TIME, 54 #ifdef CONFIG_DEBUG_BLK_CGROUP 55 BLKIO_STAT_AVG_QUEUE_SIZE, 56 BLKIO_STAT_IDLE_TIME, 57 BLKIO_STAT_EMPTY_TIME, 58 BLKIO_STAT_GROUP_WAIT_TIME, 59 BLKIO_STAT_DEQUEUE 60 #endif 61 }; 62 63 enum stat_sub_type { 64 BLKIO_STAT_READ = 0, 65 BLKIO_STAT_WRITE, 66 BLKIO_STAT_SYNC, 67 BLKIO_STAT_ASYNC, 68 BLKIO_STAT_TOTAL 69 }; 70 71 /* blkg state flags */ 72 enum blkg_state_flags { 73 BLKG_waiting = 0, 74 BLKG_idling, 75 BLKG_empty, 76 }; 77 78 /* cgroup files owned by proportional weight policy */ 79 enum blkcg_file_name_prop { 80 BLKIO_PROP_weight = 1, 81 BLKIO_PROP_weight_device, 82 BLKIO_PROP_io_service_bytes, 83 BLKIO_PROP_io_serviced, 84 BLKIO_PROP_time, 85 BLKIO_PROP_sectors, 86 BLKIO_PROP_unaccounted_time, 87 BLKIO_PROP_io_service_time, 88 BLKIO_PROP_io_wait_time, 89 BLKIO_PROP_io_merged, 90 BLKIO_PROP_io_queued, 91 BLKIO_PROP_avg_queue_size, 92 BLKIO_PROP_group_wait_time, 93 BLKIO_PROP_idle_time, 94 BLKIO_PROP_empty_time, 95 BLKIO_PROP_dequeue, 96 }; 97 98 /* cgroup files owned by throttle policy */ 99 enum blkcg_file_name_throtl { 100 BLKIO_THROTL_read_bps_device, 101 BLKIO_THROTL_write_bps_device, 102 BLKIO_THROTL_read_iops_device, 103 BLKIO_THROTL_write_iops_device, 104 BLKIO_THROTL_io_service_bytes, 105 BLKIO_THROTL_io_serviced, 106 }; 107 108 struct blkio_cgroup { 109 struct cgroup_subsys_state css; 110 unsigned int weight; 111 spinlock_t lock; 112 struct hlist_head blkg_list; 113 struct list_head policy_list; /* list of blkio_policy_node */ 114 }; 115 116 struct blkio_group_stats { 117 /* total disk time and nr sectors dispatched by this group */ 118 uint64_t time; 119 uint64_t sectors; 120 /* Time not charged to this cgroup */ 121 uint64_t unaccounted_time; 122 uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL]; 123 #ifdef CONFIG_DEBUG_BLK_CGROUP 124 /* Sum of number of IOs queued across all samples */ 125 uint64_t avg_queue_size_sum; 126 /* Count of samples taken for average */ 127 uint64_t avg_queue_size_samples; 128 /* How many times this group has been removed from service tree */ 129 unsigned long dequeue; 130 131 /* Total time spent waiting for it to be assigned a timeslice. */ 132 uint64_t group_wait_time; 133 uint64_t start_group_wait_time; 134 135 /* Time spent idling for this blkio_group */ 136 uint64_t idle_time; 137 uint64_t start_idle_time; 138 /* 139 * Total time when we have requests queued and do not contain the 140 * current active queue. 141 */ 142 uint64_t empty_time; 143 uint64_t start_empty_time; 144 uint16_t flags; 145 #endif 146 }; 147 148 struct blkio_group { 149 /* An rcu protected unique identifier for the group */ 150 void *key; 151 struct hlist_node blkcg_node; 152 unsigned short blkcg_id; 153 /* Store cgroup path */ 154 char path[128]; 155 /* The device MKDEV(major, minor), this group has been created for */ 156 dev_t dev; 157 /* policy which owns this blk group */ 158 enum blkio_policy_id plid; 159 160 /* Need to serialize the stats in the case of reset/update */ 161 spinlock_t stats_lock; 162 struct blkio_group_stats stats; 163 }; 164 165 struct blkio_policy_node { 166 struct list_head node; 167 dev_t dev; 168 /* This node belongs to max bw policy or porportional weight policy */ 169 enum blkio_policy_id plid; 170 /* cgroup file to which this rule belongs to */ 171 int fileid; 172 173 union { 174 unsigned int weight; 175 /* 176 * Rate read/write in terms of byptes per second 177 * Whether this rate represents read or write is determined 178 * by file type "fileid". 179 */ 180 u64 bps; 181 unsigned int iops; 182 } val; 183 }; 184 185 extern unsigned int blkcg_get_weight(struct blkio_cgroup *blkcg, 186 dev_t dev); 187 extern uint64_t blkcg_get_read_bps(struct blkio_cgroup *blkcg, 188 dev_t dev); 189 extern uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, 190 dev_t dev); 191 extern unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, 192 dev_t dev); 193 extern unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, 194 dev_t dev); 195 196 typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg); 197 198 typedef void (blkio_update_group_weight_fn) (void *key, 199 struct blkio_group *blkg, unsigned int weight); 200 typedef void (blkio_update_group_read_bps_fn) (void * key, 201 struct blkio_group *blkg, u64 read_bps); 202 typedef void (blkio_update_group_write_bps_fn) (void *key, 203 struct blkio_group *blkg, u64 write_bps); 204 typedef void (blkio_update_group_read_iops_fn) (void *key, 205 struct blkio_group *blkg, unsigned int read_iops); 206 typedef void (blkio_update_group_write_iops_fn) (void *key, 207 struct blkio_group *blkg, unsigned int write_iops); 208 209 struct blkio_policy_ops { 210 blkio_unlink_group_fn *blkio_unlink_group_fn; 211 blkio_update_group_weight_fn *blkio_update_group_weight_fn; 212 blkio_update_group_read_bps_fn *blkio_update_group_read_bps_fn; 213 blkio_update_group_write_bps_fn *blkio_update_group_write_bps_fn; 214 blkio_update_group_read_iops_fn *blkio_update_group_read_iops_fn; 215 blkio_update_group_write_iops_fn *blkio_update_group_write_iops_fn; 216 }; 217 218 struct blkio_policy_type { 219 struct list_head list; 220 struct blkio_policy_ops ops; 221 enum blkio_policy_id plid; 222 }; 223 224 /* Blkio controller policy registration */ 225 extern void blkio_policy_register(struct blkio_policy_type *); 226 extern void blkio_policy_unregister(struct blkio_policy_type *); 227 228 static inline char *blkg_path(struct blkio_group *blkg) 229 { 230 return blkg->path; 231 } 232 233 #else 234 235 struct blkio_group { 236 }; 237 238 struct blkio_policy_type { 239 }; 240 241 static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { } 242 static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { } 243 244 static inline char *blkg_path(struct blkio_group *blkg) { return NULL; } 245 246 #endif 247 248 #define BLKIO_WEIGHT_MIN 10 249 #define BLKIO_WEIGHT_MAX 1000 250 #define BLKIO_WEIGHT_DEFAULT 500 251 252 #ifdef CONFIG_DEBUG_BLK_CGROUP 253 void blkiocg_update_avg_queue_size_stats(struct blkio_group *blkg); 254 void blkiocg_update_dequeue_stats(struct blkio_group *blkg, 255 unsigned long dequeue); 256 void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg); 257 void blkiocg_update_idle_time_stats(struct blkio_group *blkg); 258 void blkiocg_set_start_empty_time(struct blkio_group *blkg); 259 260 #define BLKG_FLAG_FNS(name) \ 261 static inline void blkio_mark_blkg_##name( \ 262 struct blkio_group_stats *stats) \ 263 { \ 264 stats->flags |= (1 << BLKG_##name); \ 265 } \ 266 static inline void blkio_clear_blkg_##name( \ 267 struct blkio_group_stats *stats) \ 268 { \ 269 stats->flags &= ~(1 << BLKG_##name); \ 270 } \ 271 static inline int blkio_blkg_##name(struct blkio_group_stats *stats) \ 272 { \ 273 return (stats->flags & (1 << BLKG_##name)) != 0; \ 274 } \ 275 276 BLKG_FLAG_FNS(waiting) 277 BLKG_FLAG_FNS(idling) 278 BLKG_FLAG_FNS(empty) 279 #undef BLKG_FLAG_FNS 280 #else 281 static inline void blkiocg_update_avg_queue_size_stats( 282 struct blkio_group *blkg) {} 283 static inline void blkiocg_update_dequeue_stats(struct blkio_group *blkg, 284 unsigned long dequeue) {} 285 static inline void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg) 286 {} 287 static inline void blkiocg_update_idle_time_stats(struct blkio_group *blkg) {} 288 static inline void blkiocg_set_start_empty_time(struct blkio_group *blkg) {} 289 #endif 290 291 #if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE) 292 extern struct blkio_cgroup blkio_root_cgroup; 293 extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup); 294 extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, 295 struct blkio_group *blkg, void *key, dev_t dev, 296 enum blkio_policy_id plid); 297 extern int blkiocg_del_blkio_group(struct blkio_group *blkg); 298 extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg, 299 void *key); 300 void blkiocg_update_timeslice_used(struct blkio_group *blkg, 301 unsigned long time, 302 unsigned long unaccounted_time); 303 void blkiocg_update_dispatch_stats(struct blkio_group *blkg, uint64_t bytes, 304 bool direction, bool sync); 305 void blkiocg_update_completion_stats(struct blkio_group *blkg, 306 uint64_t start_time, uint64_t io_start_time, bool direction, bool sync); 307 void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction, 308 bool sync); 309 void blkiocg_update_io_add_stats(struct blkio_group *blkg, 310 struct blkio_group *curr_blkg, bool direction, bool sync); 311 void blkiocg_update_io_remove_stats(struct blkio_group *blkg, 312 bool direction, bool sync); 313 #else 314 struct cgroup; 315 static inline struct blkio_cgroup * 316 cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; } 317 318 static inline void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, 319 struct blkio_group *blkg, void *key, dev_t dev, 320 enum blkio_policy_id plid) {} 321 322 static inline int 323 blkiocg_del_blkio_group(struct blkio_group *blkg) { return 0; } 324 325 static inline struct blkio_group * 326 blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key) { return NULL; } 327 static inline void blkiocg_update_timeslice_used(struct blkio_group *blkg, 328 unsigned long time, 329 unsigned long unaccounted_time) 330 {} 331 static inline void blkiocg_update_dispatch_stats(struct blkio_group *blkg, 332 uint64_t bytes, bool direction, bool sync) {} 333 static inline void blkiocg_update_completion_stats(struct blkio_group *blkg, 334 uint64_t start_time, uint64_t io_start_time, bool direction, 335 bool sync) {} 336 static inline void blkiocg_update_io_merged_stats(struct blkio_group *blkg, 337 bool direction, bool sync) {} 338 static inline void blkiocg_update_io_add_stats(struct blkio_group *blkg, 339 struct blkio_group *curr_blkg, bool direction, bool sync) {} 340 static inline void blkiocg_update_io_remove_stats(struct blkio_group *blkg, 341 bool direction, bool sync) {} 342 #endif 343 #endif /* _BLK_CGROUP_H */ 344