aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c52
-rw-r--r--block/blk-merge.c11
-rw-r--r--block/genhd.c20
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
80void blk_queue_congestion_threshold(struct request_queue *q) 81void 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 */
1000void disk_round_stats(struct gendisk *disk) 1001void 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}
1014EXPORT_SYMBOL_GPL(disk_round_stats); 1015EXPORT_SYMBOL_GPL(disk_round_stats);
1015 1016
1016void part_round_stats(struct hd_struct *part) 1017void 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)),