[PATCH 0/2 v7] blk: fix a wrong accounting of hd_struct->in_flight

From: Satoru Takeuchi
Date: Wed Dec 08 2010 - 00:43:38 EST


From: Satoru Takeuchi <takeuchi_satoru@xxxxxxxxxxxxxx>

This patch fixes the problem that Yasuaki reported on the following post:

https://lkml.org/lkml/2010/10/12/23

How to fix:

Does not change the target partition of diskstat accounting after
merging multiple IOs so that in_flight will not go out of the sync.
It is achieved by keeping track of the sector number against which
we do the accounting.

Signed-off-by: Satoru Takeuchi <takeuchi_satoru@xxxxxxxxxxxxxx>
Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@xxxxxxxxxxxxxx>
Tested-by: Yasuaki Ishimatsu <isimatu.yasuaki@xxxxxxxxxxxxxx>

---
block/blk-core.c | 12 +++++++-----
block/blk-merge.c | 2 +-
include/linux/blkdev.h | 7 +++++++
3 files changed, 15 insertions(+), 6 deletions(-)

Index: linux-2.6.37-rc5/block/blk-core.c
===================================================================
--- linux-2.6.37-rc5.orig/block/blk-core.c 2010-12-07 13:09:04.000000000 +0900
+++ linux-2.6.37-rc5/block/blk-core.c 2010-12-08 09:42:40.000000000 +0900
@@ -64,11 +64,13 @@ static void drive_stat_acct(struct reque
return;

cpu = part_stat_lock();
- part = disk_map_sector_rcu(rq->rq_disk, blk_rq_pos(rq));

- if (!new_io)
+ if (!new_io) {
+ part = disk_map_sector_rcu(rq->rq_disk, blk_rq_acct_pos(rq));
part_stat_inc(cpu, part, merges[rw]);
- else {
+ } else {
+ rq->__acct_sector = rq->__sector;
+ part = disk_map_sector_rcu(rq->rq_disk, blk_rq_acct_pos(rq));
part_round_stats(cpu, part);
part_inc_in_flight(part, rw);
}
@@ -1776,7 +1778,7 @@ static void blk_account_io_completion(st
int cpu;

cpu = part_stat_lock();
- part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
+ part = disk_map_sector_rcu(req->rq_disk, blk_rq_acct_pos(req));
part_stat_add(cpu, part, sectors[rw], bytes >> 9);
part_stat_unlock();
}
@@ -1796,7 +1798,7 @@ static void blk_account_io_done(struct r
int cpu;

cpu = part_stat_lock();
- part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
+ part = disk_map_sector_rcu(req->rq_disk, blk_rq_acct_pos(req));

part_stat_inc(cpu, part, ios[rw]);
part_stat_add(cpu, part, ticks[rw], duration);
Index: linux-2.6.37-rc5/block/blk-merge.c
===================================================================
--- linux-2.6.37-rc5.orig/block/blk-merge.c 2010-12-07 13:09:04.000000000 +0900
+++ linux-2.6.37-rc5/block/blk-merge.c 2010-12-08 09:43:50.000000000 +0900
@@ -351,7 +351,7 @@ static void blk_account_io_merge(struct
int cpu;

cpu = part_stat_lock();
- part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
+ part = disk_map_sector_rcu(req->rq_disk, blk_rq_acct_pos(req));

part_round_stats(cpu, part);
part_dec_in_flight(part, rq_data_dir(req));
Index: linux-2.6.37-rc5/include/linux/blkdev.h
===================================================================
--- linux-2.6.37-rc5.orig/include/linux/blkdev.h 2010-12-07 13:09:04.000000000 +0900
+++ linux-2.6.37-rc5/include/linux/blkdev.h 2010-12-08 13:58:02.000000000 +0900
@@ -91,6 +91,7 @@ struct request {
/* the following two fields are internal, NEVER access directly */
unsigned int __data_len; /* total data len */
sector_t __sector; /* sector cursor */
+ sector_t __acct_sector; /* sector cursor for accounting */

struct bio *bio;
struct bio *biotail;
@@ -719,6 +720,7 @@ static inline struct request_queue *bdev

/*
* blk_rq_pos() : the current sector
+ * blk_rq_acct_pos() : the sector for accounting
* blk_rq_bytes() : bytes left in the entire request
* blk_rq_cur_bytes() : bytes left in the current segment
* blk_rq_err_bytes() : bytes left till the next error boundary
@@ -730,6 +732,11 @@ static inline sector_t blk_rq_pos(const
return rq->__sector;
}

+static inline sector_t blk_rq_acct_pos(const struct request *rq)
+{
+ return rq->__acct_sector;
+}
+
static inline unsigned int blk_rq_bytes(const struct request *rq)
{
return rq->__data_len;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/