@@ -183,6 +183,10 @@ struct throtl_grp {
struct blkg_rwstat wait_time;
/* total IOs completed */
struct blkg_rwstat completed;
+ /* total bytes throttled */
+ struct blkg_rwstat total_bytes_queued;
+ /* total IOs throttled */
+ struct blkg_rwstat total_io_queued;
};
/* We measure latency for request size from <= 4k to >= 1M */
@@ -496,7 +500,9 @@ static struct blkg_policy_data *throtl_pd_alloc(gfp_t gfp, int node)
if (blkg_rwstat_init(&tg->service_time, gfp) ||
blkg_rwstat_init(&tg->wait_time, gfp) ||
- blkg_rwstat_init(&tg->completed, gfp))
+ blkg_rwstat_init(&tg->completed, gfp) ||
+ blkg_rwstat_init(&tg->total_bytes_queued, gfp) ||
+ blkg_rwstat_init(&tg->total_io_queued, gfp))
goto err;
throtl_service_queue_init(&tg->service_queue);
@@ -528,6 +534,8 @@ static struct blkg_policy_data *throtl_pd_alloc(gfp_t gfp, int node)
blkg_rwstat_exit(&tg->service_time);
blkg_rwstat_exit(&tg->wait_time);
blkg_rwstat_exit(&tg->completed);
+ blkg_rwstat_exit(&tg->total_bytes_queued);
+ blkg_rwstat_exit(&tg->total_io_queued);
kfree(tg);
return NULL;
}
@@ -630,6 +638,10 @@ static void throtl_pd_offline(struct blkg_policy_data *pd)
&tg->wait_time);
blkg_rwstat_add_aux(&blkg_to_tg(parent)->completed,
&tg->completed);
+ blkg_rwstat_add_aux(&blkg_to_tg(parent)->total_bytes_queued,
+ &tg->total_bytes_queued);
+ blkg_rwstat_add_aux(&blkg_to_tg(parent)->total_io_queued,
+ &tg->total_io_queued);
}
}
@@ -641,6 +653,8 @@ static void throtl_pd_free(struct blkg_policy_data *pd)
blkg_rwstat_exit(&tg->service_time);
blkg_rwstat_exit(&tg->wait_time);
blkg_rwstat_exit(&tg->completed);
+ blkg_rwstat_reset(&tg->total_bytes_queued);
+ blkg_rwstat_reset(&tg->total_io_queued);
kfree(tg);
}
@@ -651,6 +665,8 @@ static void throtl_pd_reset(struct blkg_policy_data *pd)
blkg_rwstat_reset(&tg->service_time);
blkg_rwstat_reset(&tg->wait_time);
blkg_rwstat_reset(&tg->completed);
+ blkg_rwstat_reset(&tg->total_bytes_queued);
+ blkg_rwstat_reset(&tg->total_io_queued);
}
static struct throtl_grp *
@@ -1170,6 +1186,9 @@ static void throtl_add_bio_tg(struct bio *bio, struct throtl_qnode *qn,
throtl_qnode_add_bio(bio, qn, &sq->queued[rw]);
sq->nr_queued[rw]++;
+ blkg_rwstat_add(&tg->total_bytes_queued, bio_op(bio),
+ throtl_bio_data_size(bio));
+ blkg_rwstat_add(&tg->total_io_queued, bio_op(bio), 1);
throtl_enqueue_tg(tg);
}
@@ -1641,6 +1660,16 @@ static int tg_print_rwstat(struct seq_file *sf, void *v)
.private = offsetof(struct throtl_grp, completed),
.seq_show = tg_print_rwstat,
},
+ {
+ .name = "throttle.total_bytes_queued",
+ .private = offsetof(struct throtl_grp, total_bytes_queued),
+ .seq_show = tg_print_rwstat,
+ },
+ {
+ .name = "throttle.total_io_queued",
+ .private = offsetof(struct throtl_grp, total_io_queued),
+ .seq_show = tg_print_rwstat,
+ },
{ } /* terminate */
};
Add another 2 interfaces to stat io throttle information: blkio.throttle.total_io_queued blkio.throttle.total_bytes_queued These interfaces are used for monitoring throttled io/bytes and analyzing if delay has relations with io throttle. Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com> --- block/blk-throttle.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)