blk-cgroup.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. #include <linux/cgroup.h>
  16. #if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
  17. #ifndef CONFIG_BLK_CGROUP
  18. /* When blk-cgroup is a module, its subsys_id isn't a compile-time constant */
  19. extern struct cgroup_subsys blkio_subsys;
  20. #define blkio_subsys_id blkio_subsys.subsys_id
  21. #endif
  22. enum stat_type {
  23. /* Total time spent (in ns) between request dispatch to the driver and
  24. * request completion for IOs doen by this cgroup. This may not be
  25. * accurate when NCQ is turned on. */
  26. BLKIO_STAT_SERVICE_TIME = 0,
  27. /* Total bytes transferred */
  28. BLKIO_STAT_SERVICE_BYTES,
  29. /* Total IOs serviced, post merge */
  30. BLKIO_STAT_SERVICED,
  31. /* Total time spent waiting in scheduler queue in ns */
  32. BLKIO_STAT_WAIT_TIME,
  33. /* Number of IOs merged */
  34. BLKIO_STAT_MERGED,
  35. /* Number of IOs queued up */
  36. BLKIO_STAT_QUEUED,
  37. /* All the single valued stats go below this */
  38. BLKIO_STAT_TIME,
  39. BLKIO_STAT_SECTORS,
  40. #ifdef CONFIG_DEBUG_BLK_CGROUP
  41. BLKIO_STAT_AVG_QUEUE_SIZE,
  42. BLKIO_STAT_IDLE_TIME,
  43. BLKIO_STAT_EMPTY_TIME,
  44. BLKIO_STAT_GROUP_WAIT_TIME,
  45. BLKIO_STAT_DEQUEUE
  46. #endif
  47. };
  48. enum stat_sub_type {
  49. BLKIO_STAT_READ = 0,
  50. BLKIO_STAT_WRITE,
  51. BLKIO_STAT_SYNC,
  52. BLKIO_STAT_ASYNC,
  53. BLKIO_STAT_TOTAL
  54. };
  55. /* blkg state flags */
  56. enum blkg_state_flags {
  57. BLKG_waiting = 0,
  58. BLKG_idling,
  59. BLKG_empty,
  60. };
  61. struct blkio_cgroup {
  62. struct cgroup_subsys_state css;
  63. unsigned int weight;
  64. spinlock_t lock;
  65. struct hlist_head blkg_list;
  66. struct list_head policy_list; /* list of blkio_policy_node */
  67. };
  68. struct blkio_group_stats {
  69. /* total disk time and nr sectors dispatched by this group */
  70. uint64_t time;
  71. uint64_t sectors;
  72. uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL];
  73. #ifdef CONFIG_DEBUG_BLK_CGROUP
  74. /* Sum of number of IOs queued across all samples */
  75. uint64_t avg_queue_size_sum;
  76. /* Count of samples taken for average */
  77. uint64_t avg_queue_size_samples;
  78. /* How many times this group has been removed from service tree */
  79. unsigned long dequeue;
  80. /* Total time spent waiting for it to be assigned a timeslice. */
  81. uint64_t group_wait_time;
  82. uint64_t start_group_wait_time;
  83. /* Time spent idling for this blkio_group */
  84. uint64_t idle_time;
  85. uint64_t start_idle_time;
  86. /*
  87. * Total time when we have requests queued and do not contain the
  88. * current active queue.
  89. */
  90. uint64_t empty_time;
  91. uint64_t start_empty_time;
  92. uint16_t flags;
  93. #endif
  94. };
  95. struct blkio_group {
  96. /* An rcu protected unique identifier for the group */
  97. void *key;
  98. struct hlist_node blkcg_node;
  99. unsigned short blkcg_id;
  100. /* Store cgroup path */
  101. char path[128];
  102. /* The device MKDEV(major, minor), this group has been created for */
  103. dev_t dev;
  104. /* Need to serialize the stats in the case of reset/update */
  105. spinlock_t stats_lock;
  106. struct blkio_group_stats stats;
  107. };
  108. struct blkio_policy_node {
  109. struct list_head node;
  110. dev_t dev;
  111. unsigned int weight;
  112. };
  113. extern unsigned int blkcg_get_weight(struct blkio_cgroup *blkcg,
  114. dev_t dev);
  115. typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg);
  116. typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg,
  117. unsigned int weight);
  118. struct blkio_policy_ops {
  119. blkio_unlink_group_fn *blkio_unlink_group_fn;
  120. blkio_update_group_weight_fn *blkio_update_group_weight_fn;
  121. };
  122. struct blkio_policy_type {
  123. struct list_head list;
  124. struct blkio_policy_ops ops;
  125. };
  126. /* Blkio controller policy registration */
  127. extern void blkio_policy_register(struct blkio_policy_type *);
  128. extern void blkio_policy_unregister(struct blkio_policy_type *);
  129. static inline char *blkg_path(struct blkio_group *blkg)
  130. {
  131. return blkg->path;
  132. }
  133. #else
  134. struct blkio_group {
  135. };
  136. struct blkio_policy_type {
  137. };
  138. static inline void blkio_policy_register(struct blkio_policy_type *blkiop) { }
  139. static inline void blkio_policy_unregister(struct blkio_policy_type *blkiop) { }
  140. static inline char *blkg_path(struct blkio_group *blkg) { return NULL; }
  141. #endif
  142. #define BLKIO_WEIGHT_MIN 100
  143. #define BLKIO_WEIGHT_MAX 1000
  144. #define BLKIO_WEIGHT_DEFAULT 500
  145. #ifdef CONFIG_DEBUG_BLK_CGROUP
  146. void blkiocg_update_avg_queue_size_stats(struct blkio_group *blkg);
  147. void blkiocg_update_dequeue_stats(struct blkio_group *blkg,
  148. unsigned long dequeue);
  149. void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg);
  150. void blkiocg_update_idle_time_stats(struct blkio_group *blkg);
  151. void blkiocg_set_start_empty_time(struct blkio_group *blkg);
  152. #define BLKG_FLAG_FNS(name) \
  153. static inline void blkio_mark_blkg_##name( \
  154. struct blkio_group_stats *stats) \
  155. { \
  156. stats->flags |= (1 << BLKG_##name); \
  157. } \
  158. static inline void blkio_clear_blkg_##name( \
  159. struct blkio_group_stats *stats) \
  160. { \
  161. stats->flags &= ~(1 << BLKG_##name); \
  162. } \
  163. static inline int blkio_blkg_##name(struct blkio_group_stats *stats) \
  164. { \
  165. return (stats->flags & (1 << BLKG_##name)) != 0; \
  166. } \
  167. BLKG_FLAG_FNS(waiting)
  168. BLKG_FLAG_FNS(idling)
  169. BLKG_FLAG_FNS(empty)
  170. #undef BLKG_FLAG_FNS
  171. #else
  172. static inline void blkiocg_update_avg_queue_size_stats(
  173. struct blkio_group *blkg) {}
  174. static inline void blkiocg_update_dequeue_stats(struct blkio_group *blkg,
  175. unsigned long dequeue) {}
  176. static inline void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg)
  177. {}
  178. static inline void blkiocg_update_idle_time_stats(struct blkio_group *blkg) {}
  179. static inline void blkiocg_set_start_empty_time(struct blkio_group *blkg) {}
  180. #endif
  181. #if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
  182. extern struct blkio_cgroup blkio_root_cgroup;
  183. extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup);
  184. extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
  185. struct blkio_group *blkg, void *key, dev_t dev);
  186. extern int blkiocg_del_blkio_group(struct blkio_group *blkg);
  187. extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg,
  188. void *key);
  189. void blkiocg_update_timeslice_used(struct blkio_group *blkg,
  190. unsigned long time);
  191. void blkiocg_update_dispatch_stats(struct blkio_group *blkg, uint64_t bytes,
  192. bool direction, bool sync);
  193. void blkiocg_update_completion_stats(struct blkio_group *blkg,
  194. uint64_t start_time, uint64_t io_start_time, bool direction, bool sync);
  195. void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction,
  196. bool sync);
  197. void blkiocg_update_io_add_stats(struct blkio_group *blkg,
  198. struct blkio_group *curr_blkg, bool direction, bool sync);
  199. void blkiocg_update_io_remove_stats(struct blkio_group *blkg,
  200. bool direction, bool sync);
  201. #else
  202. struct cgroup;
  203. static inline struct blkio_cgroup *
  204. cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; }
  205. static inline void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
  206. struct blkio_group *blkg, void *key, dev_t dev) {}
  207. static inline int
  208. blkiocg_del_blkio_group(struct blkio_group *blkg) { return 0; }
  209. static inline struct blkio_group *
  210. blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key) { return NULL; }
  211. static inline void blkiocg_update_timeslice_used(struct blkio_group *blkg,
  212. unsigned long time) {}
  213. static inline void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
  214. uint64_t bytes, bool direction, bool sync) {}
  215. static inline void blkiocg_update_completion_stats(struct blkio_group *blkg,
  216. uint64_t start_time, uint64_t io_start_time, bool direction,
  217. bool sync) {}
  218. static inline void blkiocg_update_io_merged_stats(struct blkio_group *blkg,
  219. bool direction, bool sync) {}
  220. static inline void blkiocg_update_io_add_stats(struct blkio_group *blkg,
  221. struct blkio_group *curr_blkg, bool direction, bool sync) {}
  222. static inline void blkiocg_update_io_remove_stats(struct blkio_group *blkg,
  223. bool direction, bool sync) {}
  224. #endif
  225. #endif /* _BLK_CGROUP_H */