ck: block: add counter to track io request's d2c time

to #32700522

Indeed tool iostat's await is not good enough, which is somewhat sketchy
and could not show request's latency on device driver's side.

Here we add a new counter to track io request's d2c time, also with this
patch, we can extend iostat to show this value easily.

Note:
I had checked how iostat is implemented, it just reads fields it needs,
so iostat won't be affected by this change, so does tsar.

Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
This commit is contained in:
Xiaoguang Wang 2021-03-11 11:59:15 +08:00 committed by Qiao Ma
parent f0953dd590
commit 77ccb447ed
4 changed files with 27 additions and 4 deletions

View File

@ -131,6 +131,12 @@ Field 16 -- # of flush requests completed
Field 17 -- # of milliseconds spent flushing
This is the total number of milliseconds spent by all flush requests.
Field 18 -- # of milliseconds spent reading on device driver's side
Field 19 -- # of milliseconds spent writing on device driver's side
Field 20 -- # of milliseconds spent discarding on device driver's side
To avoid introducing performance bottlenecks, no locks are held while
modifying these counters. This implies that minor inaccuracies may be
introduced when changes collide, so (for instance) adding up all the

View File

@ -1314,6 +1314,10 @@ void blk_account_io_done(struct request *req, u64 now)
update_io_ticks(part, jiffies, true);
part_stat_inc(part, ios[sgrp]);
part_stat_add(part, nsecs[sgrp], now - req->start_time_ns);
if (req->io_start_time_ns) {
part_stat_add(part, d2c_nsecs[sgrp],
now - req->io_start_time_ns);
}
part_stat_unlock();
hd_struct_put(part);

View File

@ -103,6 +103,7 @@ static void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
for (group = 0; group < NR_STAT_GROUPS; group++) {
stat->nsecs[group] += ptr->nsecs[group];
stat->d2c_nsecs[group] += ptr->d2c_nsecs[group];
stat->sectors[group] += ptr->sectors[group];
stat->ios[group] += ptr->ios[group];
stat->merges[group] += ptr->merges[group];
@ -1304,7 +1305,8 @@ ssize_t part_stat_show(struct device *dev,
"%8lu %8lu %8llu %8u "
"%8u %8u %8u "
"%8lu %8lu %8llu %8u "
"%8lu %8u"
"%8lu %8u "
"%8u %8u %8u"
"\n",
stat.ios[STAT_READ],
stat.merges[STAT_READ],
@ -1326,7 +1328,10 @@ ssize_t part_stat_show(struct device *dev,
(unsigned long long)stat.sectors[STAT_DISCARD],
(unsigned int)div_u64(stat.nsecs[STAT_DISCARD], NSEC_PER_MSEC),
stat.ios[STAT_FLUSH],
(unsigned int)div_u64(stat.nsecs[STAT_FLUSH], NSEC_PER_MSEC));
(unsigned int)div_u64(stat.nsecs[STAT_FLUSH], NSEC_PER_MSEC),
(unsigned int)div_u64(stat.d2c_nsecs[STAT_READ], NSEC_PER_MSEC),
(unsigned int)div_u64(stat.d2c_nsecs[STAT_WRITE], NSEC_PER_MSEC),
(unsigned int)div_u64(stat.d2c_nsecs[STAT_DISCARD], NSEC_PER_MSEC));
}
ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr,
@ -1626,7 +1631,8 @@ static int diskstats_show(struct seq_file *seqf, void *v)
"%lu %lu %lu %u "
"%u %u %u "
"%lu %lu %lu %u "
"%lu %u"
"%lu %u "
"%u %u %u"
"\n",
MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
disk_name(gp, hd->partno, buf),
@ -1654,7 +1660,13 @@ static int diskstats_show(struct seq_file *seqf, void *v)
NSEC_PER_MSEC),
stat.ios[STAT_FLUSH],
(unsigned int)div_u64(stat.nsecs[STAT_FLUSH],
NSEC_PER_MSEC)
NSEC_PER_MSEC),
(unsigned int)div_u64(stat.d2c_nsecs[STAT_READ],
NSEC_PER_MSEC),
(unsigned int)div_u64(stat.d2c_nsecs[STAT_WRITE],
NSEC_PER_MSEC),
(unsigned int)div_u64(stat.d2c_nsecs[STAT_DISCARD],
NSEC_PER_MSEC)
);
}
disk_part_iter_exit(&piter);

View File

@ -6,6 +6,7 @@
struct disk_stats {
u64 nsecs[NR_STAT_GROUPS];
u64 d2c_nsecs[NR_STAT_GROUPS];
unsigned long sectors[NR_STAT_GROUPS];
unsigned long ios[NR_STAT_GROUPS];
unsigned long merges[NR_STAT_GROUPS];