aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-cgroup.h
diff options
context:
space:
mode:
authorDivyesh Shah <dpshah@google.com>2010-04-09 00:15:35 -0400
committerJens Axboe <jens.axboe@oracle.com>2010-04-09 02:36:08 -0400
commit812df48d127365ffd0869aa139738f572a86759c (patch)
tree772ef559057cd432ad874cd429287e7a912b1bb3 /block/blk-cgroup.h
parentcdc1184cf4a7bd99f5473a91244197accc49146b (diff)
blkio: Add more debug-only per-cgroup stats
1) group_wait_time - This is the amount of time the cgroup had to wait to get a timeslice for one of its queues from when it became busy, i.e., went from 0 to 1 request queued. This is different from the io_wait_time which is the cumulative total of the amount of time spent by each IO in that cgroup waiting in the scheduler queue. This stat is a great way to find out any jobs in the fleet that are being starved or waiting for longer than what is expected (due to an IO controller bug or any other issue). 2) empty_time - This is the amount of time a cgroup spends w/o any pending requests. This stat is useful when a job does not seem to be able to use its assigned disk share by helping check if that is happening due to an IO controller bug or because the job is not submitting enough IOs. 3) idle_time - This is the amount of time spent by the IO scheduler idling for a given cgroup in anticipation of a better request than the exising ones from other queues/cgroups. All these stats are recorded using start and stop events. When reading these stats, we do not add the delta between the current time and the last start time if we're between the start and stop events. We avoid doing this to make sure that these numbers are always monotonically increasing when read. Since we're using sched_clock() which may use the tsc as its source, it may induce some inconsistency (due to tsc resync across cpus) if we included the current delta. Signed-off-by: Divyesh Shah<dpshah@google.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/blk-cgroup.h')
-rw-r--r--block/blk-cgroup.h54
1 files changed, 54 insertions, 0 deletions
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
index bea7f3b9a88e..bfce085b1962 100644
--- a/block/blk-cgroup.h
+++ b/block/blk-cgroup.h
@@ -43,6 +43,9 @@ enum stat_type {
43 BLKIO_STAT_SECTORS, 43 BLKIO_STAT_SECTORS,
44#ifdef CONFIG_DEBUG_BLK_CGROUP 44#ifdef CONFIG_DEBUG_BLK_CGROUP
45 BLKIO_STAT_AVG_QUEUE_SIZE, 45 BLKIO_STAT_AVG_QUEUE_SIZE,
46 BLKIO_STAT_IDLE_TIME,
47 BLKIO_STAT_EMPTY_TIME,
48 BLKIO_STAT_GROUP_WAIT_TIME,
46 BLKIO_STAT_DEQUEUE 49 BLKIO_STAT_DEQUEUE
47#endif 50#endif
48}; 51};
@@ -55,6 +58,13 @@ enum stat_sub_type {
55 BLKIO_STAT_TOTAL 58 BLKIO_STAT_TOTAL
56}; 59};
57 60
61/* blkg state flags */
62enum blkg_state_flags {
63 BLKG_waiting = 0,
64 BLKG_idling,
65 BLKG_empty,
66};
67
58struct blkio_cgroup { 68struct blkio_cgroup {
59 struct cgroup_subsys_state css; 69 struct cgroup_subsys_state css;
60 unsigned int weight; 70 unsigned int weight;
@@ -74,6 +84,21 @@ struct blkio_group_stats {
74 uint64_t avg_queue_size_samples; 84 uint64_t avg_queue_size_samples;
75 /* How many times this group has been removed from service tree */ 85 /* How many times this group has been removed from service tree */
76 unsigned long dequeue; 86 unsigned long dequeue;
87
88 /* Total time spent waiting for it to be assigned a timeslice. */
89 uint64_t group_wait_time;
90 uint64_t start_group_wait_time;
91
92 /* Time spent idling for this blkio_group */
93 uint64_t idle_time;
94 uint64_t start_idle_time;
95 /*
96 * Total time when we have requests queued and do not contain the
97 * current active queue.
98 */
99 uint64_t empty_time;
100 uint64_t start_empty_time;
101 uint16_t flags;
77#endif 102#endif
78}; 103};
79 104
@@ -137,12 +162,41 @@ static inline char *blkg_path(struct blkio_group *blkg)
137void blkiocg_update_set_active_queue_stats(struct blkio_group *blkg); 162void blkiocg_update_set_active_queue_stats(struct blkio_group *blkg);
138void blkiocg_update_dequeue_stats(struct blkio_group *blkg, 163void blkiocg_update_dequeue_stats(struct blkio_group *blkg,
139 unsigned long dequeue); 164 unsigned long dequeue);
165void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg);
166void blkiocg_update_idle_time_stats(struct blkio_group *blkg);
167void blkiocg_set_start_empty_time(struct blkio_group *blkg, bool ignore);
168
169#define BLKG_FLAG_FNS(name) \
170static inline void blkio_mark_blkg_##name( \
171 struct blkio_group_stats *stats) \
172{ \
173 stats->flags |= (1 << BLKG_##name); \
174} \
175static inline void blkio_clear_blkg_##name( \
176 struct blkio_group_stats *stats) \
177{ \
178 stats->flags &= ~(1 << BLKG_##name); \
179} \
180static inline int blkio_blkg_##name(struct blkio_group_stats *stats) \
181{ \
182 return (stats->flags & (1 << BLKG_##name)) != 0; \
183} \
184
185BLKG_FLAG_FNS(waiting)
186BLKG_FLAG_FNS(idling)
187BLKG_FLAG_FNS(empty)
188#undef BLKG_FLAG_FNS
140#else 189#else
141static inline char *blkg_path(struct blkio_group *blkg) { return NULL; } 190static inline char *blkg_path(struct blkio_group *blkg) { return NULL; }
142static inline void blkiocg_update_set_active_queue_stats( 191static inline void blkiocg_update_set_active_queue_stats(
143 struct blkio_group *blkg) {} 192 struct blkio_group *blkg) {}
144static inline void blkiocg_update_dequeue_stats(struct blkio_group *blkg, 193static inline void blkiocg_update_dequeue_stats(struct blkio_group *blkg,
145 unsigned long dequeue) {} 194 unsigned long dequeue) {}
195static inline void blkiocg_update_set_idle_time_stats(struct blkio_group *blkg)
196{}
197static inline void blkiocg_update_idle_time_stats(struct blkio_group *blkg) {}
198static inline void blkiocg_set_start_empty_time(struct blkio_group *blkg,
199 bool ignore) {}
146#endif 200#endif
147 201
148#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE) 202#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)