summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2005-11-01 08:35:42 +0100
committerJens Axboe <axboe@suse.de>2005-11-01 08:35:42 +0100
commitd72d904a5367ad4ca3f2c9a2ce8c3a68f0b28bf0 (patch)
treeb41aaa3ceb0aa40090adda140d143e72fd16d587 /drivers
parentd83c671fb7023f69a9582e622d01525054f23b66 (diff)
downloadlinux-d72d904a5367ad4ca3f2c9a2ce8c3a68f0b28bf0.tar.bz2
[BLOCK] Update read/write block io statistics at completion time
Right now we do it at queueing time, which works alright for reads (since they are usually sync), but not for async writes since we can queue io a lot faster than we can complete it. This makes the vmstat output look extremely bursty. Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ll_rw_blk.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 0af73512b9a8..1b272883aadf 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -2387,16 +2387,12 @@ static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
if (!blk_fs_request(rq) || !rq->rq_disk)
return;
- if (rw == READ) {
- __disk_stat_add(rq->rq_disk, read_sectors, nr_sectors);
- if (!new_io)
+ if (!new_io) {
+ if (rw == READ)
__disk_stat_inc(rq->rq_disk, read_merges);
- } else if (rw == WRITE) {
- __disk_stat_add(rq->rq_disk, write_sectors, nr_sectors);
- if (!new_io)
+ else
__disk_stat_inc(rq->rq_disk, write_merges);
- }
- if (new_io) {
+ } else {
disk_round_stats(rq->rq_disk);
rq->rq_disk->in_flight++;
}
@@ -3048,6 +3044,13 @@ static int __end_that_request_first(struct request *req, int uptodate,
(unsigned long long)req->sector);
}
+ if (blk_fs_request(req) && req->rq_disk) {
+ if (rq_data_dir(req) == READ)
+ __disk_stat_add(req->rq_disk, read_sectors, nr_bytes >> 9);
+ else
+ __disk_stat_add(req->rq_disk, write_sectors, nr_bytes >> 9);
+ }
+
total_bytes = bio_nbytes = 0;
while ((bio = req->bio) != NULL) {
int nbytes;