@@ -181,6 +181,8 @@ struct throtl_grp {
struct blkg_rwstat service_time;
/* total time spent on block throttle */
struct blkg_rwstat wait_time;
+ /* total IOs completed */
+ struct blkg_rwstat completed;
};
/* We measure latency for request size from <= 4k to >= 1M */
@@ -493,7 +495,8 @@ static struct blkg_policy_data *throtl_pd_alloc(gfp_t gfp, int node)
return NULL;
if (blkg_rwstat_init(&tg->service_time, gfp) ||
- blkg_rwstat_init(&tg->wait_time, gfp))
+ blkg_rwstat_init(&tg->wait_time, gfp) ||
+ blkg_rwstat_init(&tg->completed, gfp))
goto err;
throtl_service_queue_init(&tg->service_queue);
@@ -524,6 +527,7 @@ static struct blkg_policy_data *throtl_pd_alloc(gfp_t gfp, int node)
err:
blkg_rwstat_exit(&tg->service_time);
blkg_rwstat_exit(&tg->wait_time);
+ blkg_rwstat_exit(&tg->completed);
kfree(tg);
return NULL;
}
@@ -624,6 +628,8 @@ static void throtl_pd_offline(struct blkg_policy_data *pd)
&tg->service_time);
blkg_rwstat_add_aux(&blkg_to_tg(parent)->wait_time,
&tg->wait_time);
+ blkg_rwstat_add_aux(&blkg_to_tg(parent)->completed,
+ &tg->completed);
}
}
@@ -634,6 +640,7 @@ static void throtl_pd_free(struct blkg_policy_data *pd)
del_timer_sync(&tg->service_queue.pending_timer);
blkg_rwstat_exit(&tg->service_time);
blkg_rwstat_exit(&tg->wait_time);
+ blkg_rwstat_exit(&tg->completed);
kfree(tg);
}
@@ -643,6 +650,7 @@ 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);
}
static struct throtl_grp *
@@ -1065,6 +1073,7 @@ static void throtl_stats_update_completion(struct throtl_grp *tg,
blkg_rwstat_add(&tg->service_time, op, now - io_start_time);
if (time_after64(io_start_time, start_time))
blkg_rwstat_add(&tg->wait_time, op, io_start_time - start_time);
+ blkg_rwstat_add(&tg->completed, op, 1);
local_irq_restore(flags);
}
@@ -1627,6 +1636,11 @@ static int tg_print_rwstat(struct seq_file *sf, void *v)
.private = offsetof(struct throtl_grp, wait_time),
.seq_show = tg_print_rwstat,
},
+ {
+ .name = "throttle.io_completed",
+ .private = offsetof(struct throtl_grp, completed),
+ .seq_show = tg_print_rwstat,
+ },
{ } /* terminate */
};
Now we have counters for wait_time and service_time, so add another counter for completed ios, then the average latency can be measured. Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com> --- block/blk-throttle.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)