diff options
Diffstat (limited to 'block/blk-core.c')
-rw-r--r-- | block/blk-core.c | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index d6128d9ad601..e0a5ee36849c 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -56,25 +56,26 @@ static void drive_stat_acct(struct request *rq, int new_io) | |||
56 | { | 56 | { |
57 | struct hd_struct *part; | 57 | struct hd_struct *part; |
58 | int rw = rq_data_dir(rq); | 58 | int rw = rq_data_dir(rq); |
59 | int cpu; | ||
59 | 60 | ||
60 | if (!blk_fs_request(rq) || !rq->rq_disk) | 61 | if (!blk_fs_request(rq) || !rq->rq_disk) |
61 | return; | 62 | return; |
62 | 63 | ||
63 | rcu_read_lock(); | 64 | cpu = disk_stat_lock(); |
64 | |||
65 | part = disk_map_sector_rcu(rq->rq_disk, rq->sector); | 65 | part = disk_map_sector_rcu(rq->rq_disk, rq->sector); |
66 | |||
66 | if (!new_io) | 67 | if (!new_io) |
67 | __all_stat_inc(rq->rq_disk, part, merges[rw], rq->sector); | 68 | all_stat_inc(cpu, rq->rq_disk, part, merges[rw], rq->sector); |
68 | else { | 69 | else { |
69 | disk_round_stats(rq->rq_disk); | 70 | disk_round_stats(cpu, rq->rq_disk); |
70 | rq->rq_disk->in_flight++; | 71 | rq->rq_disk->in_flight++; |
71 | if (part) { | 72 | if (part) { |
72 | part_round_stats(part); | 73 | part_round_stats(cpu, part); |
73 | part->in_flight++; | 74 | part->in_flight++; |
74 | } | 75 | } |
75 | } | 76 | } |
76 | 77 | ||
77 | rcu_read_unlock(); | 78 | disk_stat_unlock(); |
78 | } | 79 | } |
79 | 80 | ||
80 | void blk_queue_congestion_threshold(struct request_queue *q) | 81 | void blk_queue_congestion_threshold(struct request_queue *q) |
@@ -997,7 +998,7 @@ static inline void add_request(struct request_queue *q, struct request *req) | |||
997 | * /proc/diskstats. This accounts immediately for all queue usage up to | 998 | * /proc/diskstats. This accounts immediately for all queue usage up to |
998 | * the current jiffies and restarts the counters again. | 999 | * the current jiffies and restarts the counters again. |
999 | */ | 1000 | */ |
1000 | void disk_round_stats(struct gendisk *disk) | 1001 | void disk_round_stats(int cpu, struct gendisk *disk) |
1001 | { | 1002 | { |
1002 | unsigned long now = jiffies; | 1003 | unsigned long now = jiffies; |
1003 | 1004 | ||
@@ -1005,15 +1006,15 @@ void disk_round_stats(struct gendisk *disk) | |||
1005 | return; | 1006 | return; |
1006 | 1007 | ||
1007 | if (disk->in_flight) { | 1008 | if (disk->in_flight) { |
1008 | __disk_stat_add(disk, time_in_queue, | 1009 | disk_stat_add(cpu, disk, time_in_queue, |
1009 | disk->in_flight * (now - disk->stamp)); | 1010 | disk->in_flight * (now - disk->stamp)); |
1010 | __disk_stat_add(disk, io_ticks, (now - disk->stamp)); | 1011 | disk_stat_add(cpu, disk, io_ticks, (now - disk->stamp)); |
1011 | } | 1012 | } |
1012 | disk->stamp = now; | 1013 | disk->stamp = now; |
1013 | } | 1014 | } |
1014 | EXPORT_SYMBOL_GPL(disk_round_stats); | 1015 | EXPORT_SYMBOL_GPL(disk_round_stats); |
1015 | 1016 | ||
1016 | void part_round_stats(struct hd_struct *part) | 1017 | void part_round_stats(int cpu, struct hd_struct *part) |
1017 | { | 1018 | { |
1018 | unsigned long now = jiffies; | 1019 | unsigned long now = jiffies; |
1019 | 1020 | ||
@@ -1021,9 +1022,9 @@ void part_round_stats(struct hd_struct *part) | |||
1021 | return; | 1022 | return; |
1022 | 1023 | ||
1023 | if (part->in_flight) { | 1024 | if (part->in_flight) { |
1024 | __part_stat_add(part, time_in_queue, | 1025 | part_stat_add(cpu, part, time_in_queue, |
1025 | part->in_flight * (now - part->stamp)); | 1026 | part->in_flight * (now - part->stamp)); |
1026 | __part_stat_add(part, io_ticks, (now - part->stamp)); | 1027 | part_stat_add(cpu, part, io_ticks, (now - part->stamp)); |
1027 | } | 1028 | } |
1028 | part->stamp = now; | 1029 | part->stamp = now; |
1029 | } | 1030 | } |
@@ -1563,12 +1564,13 @@ static int __end_that_request_first(struct request *req, int error, | |||
1563 | if (blk_fs_request(req) && req->rq_disk) { | 1564 | if (blk_fs_request(req) && req->rq_disk) { |
1564 | const int rw = rq_data_dir(req); | 1565 | const int rw = rq_data_dir(req); |
1565 | struct hd_struct *part; | 1566 | struct hd_struct *part; |
1567 | int cpu; | ||
1566 | 1568 | ||
1567 | rcu_read_lock(); | 1569 | cpu = disk_stat_lock(); |
1568 | part = disk_map_sector_rcu(req->rq_disk, req->sector); | 1570 | part = disk_map_sector_rcu(req->rq_disk, req->sector); |
1569 | all_stat_add(req->rq_disk, part, sectors[rw], | 1571 | all_stat_add(cpu, req->rq_disk, part, sectors[rw], |
1570 | nr_bytes >> 9, req->sector); | 1572 | nr_bytes >> 9, req->sector); |
1571 | rcu_read_unlock(); | 1573 | disk_stat_unlock(); |
1572 | } | 1574 | } |
1573 | 1575 | ||
1574 | total_bytes = bio_nbytes = 0; | 1576 | total_bytes = bio_nbytes = 0; |
@@ -1753,21 +1755,21 @@ static void end_that_request_last(struct request *req, int error) | |||
1753 | unsigned long duration = jiffies - req->start_time; | 1755 | unsigned long duration = jiffies - req->start_time; |
1754 | const int rw = rq_data_dir(req); | 1756 | const int rw = rq_data_dir(req); |
1755 | struct hd_struct *part; | 1757 | struct hd_struct *part; |
1758 | int cpu; | ||
1756 | 1759 | ||
1757 | rcu_read_lock(); | 1760 | cpu = disk_stat_lock(); |
1758 | |||
1759 | part = disk_map_sector_rcu(disk, req->sector); | 1761 | part = disk_map_sector_rcu(disk, req->sector); |
1760 | 1762 | ||
1761 | __all_stat_inc(disk, part, ios[rw], req->sector); | 1763 | all_stat_inc(cpu, disk, part, ios[rw], req->sector); |
1762 | __all_stat_add(disk, part, ticks[rw], duration, req->sector); | 1764 | all_stat_add(cpu, disk, part, ticks[rw], duration, req->sector); |
1763 | disk_round_stats(disk); | 1765 | disk_round_stats(cpu, disk); |
1764 | disk->in_flight--; | 1766 | disk->in_flight--; |
1765 | if (part) { | 1767 | if (part) { |
1766 | part_round_stats(part); | 1768 | part_round_stats(cpu, part); |
1767 | part->in_flight--; | 1769 | part->in_flight--; |
1768 | } | 1770 | } |
1769 | 1771 | ||
1770 | rcu_read_unlock(); | 1772 | disk_stat_unlock(); |
1771 | } | 1773 | } |
1772 | 1774 | ||
1773 | if (req->end_io) | 1775 | if (req->end_io) |