diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 52 | ||||
-rw-r--r-- | block/blk-merge.c | 11 | ||||
-rw-r--r-- | block/genhd.c | 20 |
3 files changed, 44 insertions, 39 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) |
diff --git a/block/blk-merge.c b/block/blk-merge.c index eb2a3ca58303..d926a24bf1fd 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -388,18 +388,19 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
388 | 388 | ||
389 | if (req->rq_disk) { | 389 | if (req->rq_disk) { |
390 | struct hd_struct *part; | 390 | struct hd_struct *part; |
391 | int cpu; | ||
391 | 392 | ||
392 | rcu_read_lock(); | 393 | cpu = disk_stat_lock(); |
393 | |||
394 | part = disk_map_sector_rcu(req->rq_disk, req->sector); | 394 | part = disk_map_sector_rcu(req->rq_disk, req->sector); |
395 | disk_round_stats(req->rq_disk); | 395 | |
396 | disk_round_stats(cpu, req->rq_disk); | ||
396 | req->rq_disk->in_flight--; | 397 | req->rq_disk->in_flight--; |
397 | if (part) { | 398 | if (part) { |
398 | part_round_stats(part); | 399 | part_round_stats(cpu, part); |
399 | part->in_flight--; | 400 | part->in_flight--; |
400 | } | 401 | } |
401 | 402 | ||
402 | rcu_read_unlock(); | 403 | disk_stat_unlock(); |
403 | } | 404 | } |
404 | 405 | ||
405 | req->ioprio = ioprio_best(req->ioprio, next->ioprio); | 406 | req->ioprio = ioprio_best(req->ioprio, next->ioprio); |
diff --git a/block/genhd.c b/block/genhd.c index b431d6543942..430626e440f0 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -633,10 +633,11 @@ static ssize_t disk_stat_show(struct device *dev, | |||
633 | struct device_attribute *attr, char *buf) | 633 | struct device_attribute *attr, char *buf) |
634 | { | 634 | { |
635 | struct gendisk *disk = dev_to_disk(dev); | 635 | struct gendisk *disk = dev_to_disk(dev); |
636 | int cpu; | ||
636 | 637 | ||
637 | preempt_disable(); | 638 | cpu = disk_stat_lock(); |
638 | disk_round_stats(disk); | 639 | disk_round_stats(cpu, disk); |
639 | preempt_enable(); | 640 | disk_stat_unlock(); |
640 | return sprintf(buf, | 641 | return sprintf(buf, |
641 | "%8lu %8lu %8llu %8u " | 642 | "%8lu %8lu %8llu %8u " |
642 | "%8lu %8lu %8llu %8u " | 643 | "%8lu %8lu %8llu %8u " |
@@ -749,6 +750,7 @@ static int diskstats_show(struct seq_file *seqf, void *v) | |||
749 | struct disk_part_iter piter; | 750 | struct disk_part_iter piter; |
750 | struct hd_struct *hd; | 751 | struct hd_struct *hd; |
751 | char buf[BDEVNAME_SIZE]; | 752 | char buf[BDEVNAME_SIZE]; |
753 | int cpu; | ||
752 | 754 | ||
753 | /* | 755 | /* |
754 | if (&gp->dev.kobj.entry == block_class.devices.next) | 756 | if (&gp->dev.kobj.entry == block_class.devices.next) |
@@ -758,9 +760,9 @@ static int diskstats_show(struct seq_file *seqf, void *v) | |||
758 | "\n\n"); | 760 | "\n\n"); |
759 | */ | 761 | */ |
760 | 762 | ||
761 | preempt_disable(); | 763 | cpu = disk_stat_lock(); |
762 | disk_round_stats(gp); | 764 | disk_round_stats(cpu, gp); |
763 | preempt_enable(); | 765 | disk_stat_unlock(); |
764 | seq_printf(seqf, "%4d %4d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n", | 766 | seq_printf(seqf, "%4d %4d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n", |
765 | MAJOR(disk_devt(gp)), MINOR(disk_devt(gp)), | 767 | MAJOR(disk_devt(gp)), MINOR(disk_devt(gp)), |
766 | disk_name(gp, 0, buf), | 768 | disk_name(gp, 0, buf), |
@@ -777,9 +779,9 @@ static int diskstats_show(struct seq_file *seqf, void *v) | |||
777 | /* now show all non-0 size partitions of it */ | 779 | /* now show all non-0 size partitions of it */ |
778 | disk_part_iter_init(&piter, gp, 0); | 780 | disk_part_iter_init(&piter, gp, 0); |
779 | while ((hd = disk_part_iter_next(&piter))) { | 781 | while ((hd = disk_part_iter_next(&piter))) { |
780 | preempt_disable(); | 782 | cpu = disk_stat_lock(); |
781 | part_round_stats(hd); | 783 | part_round_stats(cpu, hd); |
782 | preempt_enable(); | 784 | disk_stat_unlock(); |
783 | seq_printf(seqf, "%4d %4d %s %lu %lu %llu " | 785 | seq_printf(seqf, "%4d %4d %s %lu %lu %llu " |
784 | "%u %lu %lu %llu %u %u %u %u\n", | 786 | "%u %lu %lu %llu %u %u %u %u\n", |
785 | MAJOR(part_devt(hd)), MINOR(part_devt(hd)), | 787 | MAJOR(part_devt(hd)), MINOR(part_devt(hd)), |