diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2008-05-07 04:15:46 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-05-07 04:15:46 -0400 |
commit | 28f13702f03e527fcb979747a882cf366c489c50 (patch) | |
tree | 08cf04c696bf0facb083bbfbdd867e5949c5fa14 /block/blk-core.c | |
parent | 6d63c275572d1e6f00d4fa154f16fbb0d8c2d2bf (diff) |
block: avoid duplicate calls to get_part() in disk stat code
get_part() is fairly expensive, as it O(N) loops over partitions
to find the right one. In lots of normal IO paths we end up looking
up the partition twice, to make matters even worse. Change the
stat add code to accept a passed in partition instead.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/blk-core.c')
-rw-r--r-- | block/blk-core.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 1b7dddf94f4f..2987fe47b5ee 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -54,15 +54,16 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done); | |||
54 | 54 | ||
55 | static void drive_stat_acct(struct request *rq, int new_io) | 55 | static void drive_stat_acct(struct request *rq, int new_io) |
56 | { | 56 | { |
57 | struct hd_struct *part; | ||
57 | int rw = rq_data_dir(rq); | 58 | int rw = rq_data_dir(rq); |
58 | 59 | ||
59 | if (!blk_fs_request(rq) || !rq->rq_disk) | 60 | if (!blk_fs_request(rq) || !rq->rq_disk) |
60 | return; | 61 | return; |
61 | 62 | ||
62 | if (!new_io) { | 63 | part = get_part(rq->rq_disk, rq->sector); |
63 | __all_stat_inc(rq->rq_disk, merges[rw], rq->sector); | 64 | if (!new_io) |
64 | } else { | 65 | __all_stat_inc(rq->rq_disk, part, merges[rw], rq->sector); |
65 | struct hd_struct *part = get_part(rq->rq_disk, rq->sector); | 66 | else { |
66 | disk_round_stats(rq->rq_disk); | 67 | disk_round_stats(rq->rq_disk); |
67 | rq->rq_disk->in_flight++; | 68 | rq->rq_disk->in_flight++; |
68 | if (part) { | 69 | if (part) { |
@@ -1538,10 +1539,11 @@ static int __end_that_request_first(struct request *req, int error, | |||
1538 | } | 1539 | } |
1539 | 1540 | ||
1540 | if (blk_fs_request(req) && req->rq_disk) { | 1541 | if (blk_fs_request(req) && req->rq_disk) { |
1542 | struct hd_struct *part = get_part(req->rq_disk, req->sector); | ||
1541 | const int rw = rq_data_dir(req); | 1543 | const int rw = rq_data_dir(req); |
1542 | 1544 | ||
1543 | all_stat_add(req->rq_disk, sectors[rw], | 1545 | all_stat_add(req->rq_disk, part, sectors[rw], |
1544 | nr_bytes >> 9, req->sector); | 1546 | nr_bytes >> 9, req->sector); |
1545 | } | 1547 | } |
1546 | 1548 | ||
1547 | total_bytes = bio_nbytes = 0; | 1549 | total_bytes = bio_nbytes = 0; |
@@ -1727,8 +1729,8 @@ static void end_that_request_last(struct request *req, int error) | |||
1727 | const int rw = rq_data_dir(req); | 1729 | const int rw = rq_data_dir(req); |
1728 | struct hd_struct *part = get_part(disk, req->sector); | 1730 | struct hd_struct *part = get_part(disk, req->sector); |
1729 | 1731 | ||
1730 | __all_stat_inc(disk, ios[rw], req->sector); | 1732 | __all_stat_inc(disk, part, ios[rw], req->sector); |
1731 | __all_stat_add(disk, ticks[rw], duration, req->sector); | 1733 | __all_stat_add(disk, part, ticks[rw], duration, req->sector); |
1732 | disk_round_stats(disk); | 1734 | disk_round_stats(disk); |
1733 | disk->in_flight--; | 1735 | disk->in_flight--; |
1734 | if (part) { | 1736 | if (part) { |