Skip to content

Commit 5f27571

Browse files
YuKuai-huaweiaxboe
authored andcommitted
block: count 'ios' and 'sectors' when io is done for bio-based device
While using iostat for raid, I observed very strange 'await' occasionally, and turns out it's due to that 'ios' and 'sectors' is counted in bdev_start_io_acct(), while 'nsecs' is counted in bdev_end_io_acct(). I'm not sure why they are ccounted like that but I think this behaviour is obviously wrong because user will get wrong disk stats. Fix the problem by counting 'ios' and 'sectors' when io is done, like what rq-based device does. Fixes: 394ffa5 ("blk: introduce generic io stat accounting help function") Signed-off-by: Yu Kuai <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 6030363 commit 5f27571

File tree

4 files changed

+15
-20
lines changed

4 files changed

+15
-20
lines changed

block/blk-core.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -959,16 +959,11 @@ void update_io_ticks(struct block_device *part, unsigned long now, bool end)
959959
}
960960
}
961961

962-
unsigned long bdev_start_io_acct(struct block_device *bdev,
963-
unsigned int sectors, enum req_op op,
962+
unsigned long bdev_start_io_acct(struct block_device *bdev, enum req_op op,
964963
unsigned long start_time)
965964
{
966-
const int sgrp = op_stat_group(op);
967-
968965
part_stat_lock();
969966
update_io_ticks(bdev, start_time, false);
970-
part_stat_inc(bdev, ios[sgrp]);
971-
part_stat_add(bdev, sectors[sgrp], sectors);
972967
part_stat_local_inc(bdev, in_flight[op_is_write(op)]);
973968
part_stat_unlock();
974969

@@ -984,20 +979,21 @@ EXPORT_SYMBOL(bdev_start_io_acct);
984979
*/
985980
unsigned long bio_start_io_acct(struct bio *bio)
986981
{
987-
return bdev_start_io_acct(bio->bi_bdev, bio_sectors(bio),
988-
bio_op(bio), jiffies);
982+
return bdev_start_io_acct(bio->bi_bdev, bio_op(bio), jiffies);
989983
}
990984
EXPORT_SYMBOL_GPL(bio_start_io_acct);
991985

992986
void bdev_end_io_acct(struct block_device *bdev, enum req_op op,
993-
unsigned long start_time)
987+
unsigned int sectors, unsigned long start_time)
994988
{
995989
const int sgrp = op_stat_group(op);
996990
unsigned long now = READ_ONCE(jiffies);
997991
unsigned long duration = now - start_time;
998992

999993
part_stat_lock();
1000994
update_io_ticks(bdev, now, true);
995+
part_stat_inc(bdev, ios[sgrp]);
996+
part_stat_add(bdev, sectors[sgrp], sectors);
1001997
part_stat_add(bdev, nsecs[sgrp], jiffies_to_nsecs(duration));
1002998
part_stat_local_dec(bdev, in_flight[op_is_write(op)]);
1003999
part_stat_unlock();
@@ -1007,7 +1003,7 @@ EXPORT_SYMBOL(bdev_end_io_acct);
10071003
void bio_end_io_acct_remapped(struct bio *bio, unsigned long start_time,
10081004
struct block_device *orig_bdev)
10091005
{
1010-
bdev_end_io_acct(orig_bdev, bio_op(bio), start_time);
1006+
bdev_end_io_acct(orig_bdev, bio_op(bio), bio_sectors(bio), start_time);
10111007
}
10121008
EXPORT_SYMBOL_GPL(bio_end_io_acct_remapped);
10131009

drivers/md/dm.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,10 +512,10 @@ static void dm_io_acct(struct dm_io *io, bool end)
512512
sectors = io->sectors;
513513

514514
if (!end)
515-
bdev_start_io_acct(bio->bi_bdev, sectors, bio_op(bio),
516-
start_time);
515+
bdev_start_io_acct(bio->bi_bdev, bio_op(bio), start_time);
517516
else
518-
bdev_end_io_acct(bio->bi_bdev, bio_op(bio), start_time);
517+
bdev_end_io_acct(bio->bi_bdev, bio_op(bio), sectors,
518+
start_time);
519519

520520
if (static_branch_unlikely(&stats_enabled) &&
521521
unlikely(dm_stats_used(&md->stats))) {

drivers/nvme/host/multipath.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,8 @@ void nvme_mpath_start_request(struct request *rq)
123123
return;
124124

125125
nvme_req(rq)->flags |= NVME_MPATH_IO_STATS;
126-
nvme_req(rq)->start_time = bdev_start_io_acct(disk->part0,
127-
blk_rq_bytes(rq) >> SECTOR_SHIFT,
128-
req_op(rq), jiffies);
126+
nvme_req(rq)->start_time = bdev_start_io_acct(disk->part0, req_op(rq),
127+
jiffies);
129128
}
130129
EXPORT_SYMBOL_GPL(nvme_mpath_start_request);
131130

@@ -136,7 +135,8 @@ void nvme_mpath_end_request(struct request *rq)
136135
if (!(nvme_req(rq)->flags & NVME_MPATH_IO_STATS))
137136
return;
138137
bdev_end_io_acct(ns->head->disk->part0, req_op(rq),
139-
nvme_req(rq)->start_time);
138+
blk_rq_bytes(rq) >> SECTOR_SHIFT,
139+
nvme_req(rq)->start_time);
140140
}
141141

142142
void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl)

include/linux/blkdev.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,11 +1446,10 @@ static inline void blk_wake_io_task(struct task_struct *waiter)
14461446
wake_up_process(waiter);
14471447
}
14481448

1449-
unsigned long bdev_start_io_acct(struct block_device *bdev,
1450-
unsigned int sectors, enum req_op op,
1449+
unsigned long bdev_start_io_acct(struct block_device *bdev, enum req_op op,
14511450
unsigned long start_time);
14521451
void bdev_end_io_acct(struct block_device *bdev, enum req_op op,
1453-
unsigned long start_time);
1452+
unsigned int sectors, unsigned long start_time);
14541453

14551454
unsigned long bio_start_io_acct(struct bio *bio);
14561455
void bio_end_io_acct_remapped(struct bio *bio, unsigned long start_time,

0 commit comments

Comments
 (0)