History

block/diskstats: more accurate approximation of io_ticks for slow disks

Currently io_ticks is approximated by adding one at each start and end of requests if jiffies counter has changed. This works perfectly for requests shorter than a jiffy or if one of requests starts/ends at each jiffy. If disk executes just one request at a time and they are longer than two jiffies then only first and last jiffies will be accounted. Fix is simple: at the end of request add up into io_ticks jiffies passed since last update rather than just one jiffy. Example: common HDD executes random read 4k requests around 12ms. fio --name=test --filename=/dev/sdb --rw=randread --direct=1 --runtime=30 & iostat -x 10 sdb Note changes of iostat's "%util" 8,43% -> 99,99% before/after patch: Before: Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0,00 0,00 82,60 0,00 330,40 0,00 8,00 0,96 12,09 12,09 0,00 1,02 8,43 After: Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0,00 0,00 82,50 0,00 330,00 0,00 8,00 1,00 12,10 12,10 0,00 12,12 99,99 Now io_ticks does not loose time between start and end of requests, but for queue-depth > 1 some I/O time between adjacent starts might be lost. For load estimation "%util" is not as useful as average queue length, but it clearly shows how often disk queue is completely empty.

Konstantin Khlebnikov committed 6 years ago

Commit 2b8bd421 parent 387048b4 files · +11 −8Browse files

Showing the changes to include/linux (1 of 4 files). Show all

Unified · Split

include/linux/genhd.h+1−1
@@ -422,7 +422,7 @@ void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, · 421 unmodified lines
422void part_inc_in_flight(struct request_queue *q, struct hd_struct *part,422void part_inc_in_flight(struct request_queue *q, struct hd_struct *part,
423 int rw);423 int rw);
424 424
425void update_io_ticks(struct hd_struct *part, unsigned long now);425void update_io_ticks(struct hd_struct *part, unsigned long now, bool end);
426 426
427/* block/genhd.c */427/* block/genhd.c */
428extern void device_add_disk(struct device *parent, struct gendisk *disk,428extern void device_add_disk(struct device *parent, struct gendisk *disk,