__bio_start_io_acct() interface is like bio_start_io_acct() that allows start_time to be passed in. This gives drivers the ability to defer starting accounting until after IO is issued (but possibily not entirely due to bio splitting). Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx> --- block/blk-core.c | 27 ++++++++++++++++++++------- include/linux/blkdev.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 97f8bc8d3a79..18cd12fee67d 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1060,21 +1060,30 @@ void update_io_ticks(struct block_device *part, unsigned long now, bool end) } } -static unsigned long __part_start_io_acct(struct block_device *part, - unsigned int sectors, unsigned int op) +static void __part_start_io_acct(struct block_device *part, unsigned int sectors, + unsigned int op, unsigned long start_time) { const int sgrp = op_stat_group(op); - unsigned long now = READ_ONCE(jiffies); part_stat_lock(); - update_io_ticks(part, now, false); + update_io_ticks(part, start_time, false); part_stat_inc(part, ios[sgrp]); part_stat_add(part, sectors[sgrp], sectors); part_stat_local_inc(part, in_flight[op_is_write(op)]); part_stat_unlock(); +} - return now; +/** + * __bio_start_io_acct - start I/O accounting for bio based drivers + * @bio: bio to start account for + * @start_time: start time that should be passed back to bio_end_io_acct(). + */ +void __bio_start_io_acct(struct bio *bio, unsigned long start_time) +{ + __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), + bio_op(bio), start_time); } +EXPORT_SYMBOL_GPL(__bio_start_io_acct); /** * bio_start_io_acct - start I/O accounting for bio based drivers @@ -1084,14 +1093,18 @@ static unsigned long __part_start_io_acct(struct block_device *part, */ unsigned long bio_start_io_acct(struct bio *bio) { - return __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), bio_op(bio)); + unsigned long now = READ_ONCE(jiffies); + __bio_start_io_acct(bio, now); + return now; } EXPORT_SYMBOL_GPL(bio_start_io_acct); unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors, unsigned int op) { - return __part_start_io_acct(disk->part0, sectors, op); + unsigned long now = READ_ONCE(jiffies); + __part_start_io_acct(disk->part0, sectors, op, now); + return now; } EXPORT_SYMBOL(disk_start_io_acct); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9c95df26fc26..ed3cd5f7f984 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1258,6 +1258,7 @@ unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors, void disk_end_io_acct(struct gendisk *disk, unsigned int op, unsigned long start_time); +void __bio_start_io_acct(struct bio *bio, unsigned long start_time); unsigned long bio_start_io_acct(struct bio *bio); void bio_end_io_acct_remapped(struct bio *bio, unsigned long start_time, struct block_device *orig_bdev); -- 2.15.0