block: add bio_start_io_acct_time() to control start_time
authorMike Snitzer <snitzer@redhat.com>
Fri, 28 Jan 2022 15:58:39 +0000 (10:58 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Feb 2022 16:27:03 +0000 (17:27 +0100)
commit e45c47d1f94e0cc7b6b079fdb4bcce2995e2adc4 upstream.

bio_start_io_acct_time() 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).

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Link: https://lore.kernel.org/r/20220128155841.39644-2-snitzer@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
block/blk-core.c
include/linux/blkdev.h

index c2d912d0c976c022d56110a804f2a9456bfc41e4..d42a0f3ff73615c398ae396f2f3b49a5f9b546ab 100644 (file)
@@ -1293,20 +1293,32 @@ void blk_account_io_start(struct request *rq)
 }
 
 static unsigned long __part_start_io_acct(struct block_device *part,
-                                         unsigned int sectors, unsigned int op)
+                                         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;
+       return start_time;
+}
+
+/**
+ * bio_start_io_acct_time - 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_time(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_time);
 
 /**
  * bio_start_io_acct - start I/O accounting for bio based drivers
@@ -1316,14 +1328,15 @@ 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));
+       return __part_start_io_acct(bio->bi_bdev, bio_sectors(bio),
+                                   bio_op(bio), jiffies);
 }
 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);
+       return __part_start_io_acct(disk->part0, sectors, op, jiffies);
 }
 EXPORT_SYMBOL(disk_start_io_acct);
 
index 0a9fdcbbab83d1123afb0a281386e5367a590c98..be8e7a55d803cf08489f8bbe6cb3607c495da3e1 100644 (file)
@@ -1947,6 +1947,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_time(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);