diff options
author | Tejun Heo <tj@kernel.org> | 2008-08-25 06:56:14 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-10-09 02:56:08 -0400 |
commit | 074a7aca7afa6f230104e8e65eba3420263714a5 (patch) | |
tree | f418313e45bd55be8156c8a3e8f9a216cf63058d | |
parent | eddb2e26b5ee3c5da68ba4bf1921ba20e2097bff (diff) |
block: move stats from disk to part0
Move stats related fields - stamp, in_flight, dkstats - from disk to
part0 and unify stat handling such that...
* part_stat_*() now updates part0 together if the specified partition
is not part0. ie. part_stat_*() are now essentially all_stat_*().
* {disk|all}_stat_*() are gone.
* part_round_stats() is updated similary. It handles part0 stats
automatically and disk_round_stats() is killed.
* part_{inc|dec}_in_fligh() is implemented which automatically updates
part0 stats for parts other than part0.
* disk_map_sector_rcu() is updated to return part0 if no part matches.
Combined with the above changes, this makes NULL special case
handling in callers unnecessary.
* Separate stats show code paths for disk are collapsed into part
stats show code paths.
* Rename disk_stat_lock/unlock() to part_stat_lock/unlock()
While at it, reposition stat handling macros a bit and add missing
parentheses around macro parameters.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | block/blk-core.c | 84 | ||||
-rw-r--r-- | block/blk-merge.c | 12 | ||||
-rw-r--r-- | block/genhd.c | 97 | ||||
-rw-r--r-- | drivers/block/aoe/aoecmd.c | 12 | ||||
-rw-r--r-- | drivers/md/dm.c | 27 | ||||
-rw-r--r-- | drivers/md/linear.c | 9 | ||||
-rw-r--r-- | drivers/md/md.c | 4 | ||||
-rw-r--r-- | drivers/md/multipath.c | 9 | ||||
-rw-r--r-- | drivers/md/raid0.c | 9 | ||||
-rw-r--r-- | drivers/md/raid1.c | 9 | ||||
-rw-r--r-- | drivers/md/raid10.c | 9 | ||||
-rw-r--r-- | drivers/md/raid5.c | 9 | ||||
-rw-r--r-- | fs/partitions/check.c | 12 | ||||
-rw-r--r-- | include/linux/genhd.h | 159 |
14 files changed, 165 insertions, 296 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 505ec61067df..98138f002524 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -61,21 +61,17 @@ static void drive_stat_acct(struct request *rq, int new_io) | |||
61 | if (!blk_fs_request(rq) || !rq->rq_disk) | 61 | if (!blk_fs_request(rq) || !rq->rq_disk) |
62 | return; | 62 | return; |
63 | 63 | ||
64 | cpu = disk_stat_lock(); | 64 | cpu = part_stat_lock(); |
65 | part = disk_map_sector_rcu(rq->rq_disk, rq->sector); | 65 | part = disk_map_sector_rcu(rq->rq_disk, rq->sector); |
66 | 66 | ||
67 | if (!new_io) | 67 | if (!new_io) |
68 | all_stat_inc(cpu, rq->rq_disk, part, merges[rw], rq->sector); | 68 | part_stat_inc(cpu, part, merges[rw]); |
69 | else { | 69 | else { |
70 | disk_round_stats(cpu, rq->rq_disk); | 70 | part_round_stats(cpu, part); |
71 | rq->rq_disk->in_flight++; | 71 | part_inc_in_flight(part); |
72 | if (part) { | ||
73 | part_round_stats(cpu, part); | ||
74 | part->in_flight++; | ||
75 | } | ||
76 | } | 72 | } |
77 | 73 | ||
78 | disk_stat_unlock(); | 74 | part_stat_unlock(); |
79 | } | 75 | } |
80 | 76 | ||
81 | void blk_queue_congestion_threshold(struct request_queue *q) | 77 | void blk_queue_congestion_threshold(struct request_queue *q) |
@@ -983,8 +979,22 @@ static inline void add_request(struct request_queue *q, struct request *req) | |||
983 | __elv_add_request(q, req, ELEVATOR_INSERT_SORT, 0); | 979 | __elv_add_request(q, req, ELEVATOR_INSERT_SORT, 0); |
984 | } | 980 | } |
985 | 981 | ||
986 | /* | 982 | static void part_round_stats_single(int cpu, struct hd_struct *part, |
987 | * disk_round_stats() - Round off the performance stats on a struct | 983 | unsigned long now) |
984 | { | ||
985 | if (now == part->stamp) | ||
986 | return; | ||
987 | |||
988 | if (part->in_flight) { | ||
989 | __part_stat_add(cpu, part, time_in_queue, | ||
990 | part->in_flight * (now - part->stamp)); | ||
991 | __part_stat_add(cpu, part, io_ticks, (now - part->stamp)); | ||
992 | } | ||
993 | part->stamp = now; | ||
994 | } | ||
995 | |||
996 | /** | ||
997 | * part_round_stats() - Round off the performance stats on a struct | ||
988 | * disk_stats. | 998 | * disk_stats. |
989 | * | 999 | * |
990 | * The average IO queue length and utilisation statistics are maintained | 1000 | * The average IO queue length and utilisation statistics are maintained |
@@ -998,36 +1008,15 @@ static inline void add_request(struct request_queue *q, struct request *req) | |||
998 | * /proc/diskstats. This accounts immediately for all queue usage up to | 1008 | * /proc/diskstats. This accounts immediately for all queue usage up to |
999 | * the current jiffies and restarts the counters again. | 1009 | * the current jiffies and restarts the counters again. |
1000 | */ | 1010 | */ |
1001 | void disk_round_stats(int cpu, struct gendisk *disk) | ||
1002 | { | ||
1003 | unsigned long now = jiffies; | ||
1004 | |||
1005 | if (now == disk->stamp) | ||
1006 | return; | ||
1007 | |||
1008 | if (disk->in_flight) { | ||
1009 | disk_stat_add(cpu, disk, time_in_queue, | ||
1010 | disk->in_flight * (now - disk->stamp)); | ||
1011 | disk_stat_add(cpu, disk, io_ticks, (now - disk->stamp)); | ||
1012 | } | ||
1013 | disk->stamp = now; | ||
1014 | } | ||
1015 | EXPORT_SYMBOL_GPL(disk_round_stats); | ||
1016 | |||
1017 | void part_round_stats(int cpu, struct hd_struct *part) | 1011 | void part_round_stats(int cpu, struct hd_struct *part) |
1018 | { | 1012 | { |
1019 | unsigned long now = jiffies; | 1013 | unsigned long now = jiffies; |
1020 | 1014 | ||
1021 | if (now == part->stamp) | 1015 | if (part->partno) |
1022 | return; | 1016 | part_round_stats_single(cpu, &part_to_disk(part)->part0, now); |
1023 | 1017 | part_round_stats_single(cpu, part, now); | |
1024 | if (part->in_flight) { | ||
1025 | part_stat_add(cpu, part, time_in_queue, | ||
1026 | part->in_flight * (now - part->stamp)); | ||
1027 | part_stat_add(cpu, part, io_ticks, (now - part->stamp)); | ||
1028 | } | ||
1029 | part->stamp = now; | ||
1030 | } | 1018 | } |
1019 | EXPORT_SYMBOL_GPL(part_round_stats); | ||
1031 | 1020 | ||
1032 | /* | 1021 | /* |
1033 | * queue lock must be held | 1022 | * queue lock must be held |
@@ -1567,11 +1556,10 @@ static int __end_that_request_first(struct request *req, int error, | |||
1567 | struct hd_struct *part; | 1556 | struct hd_struct *part; |
1568 | int cpu; | 1557 | int cpu; |
1569 | 1558 | ||
1570 | cpu = disk_stat_lock(); | 1559 | cpu = part_stat_lock(); |
1571 | part = disk_map_sector_rcu(req->rq_disk, req->sector); | 1560 | part = disk_map_sector_rcu(req->rq_disk, req->sector); |
1572 | all_stat_add(cpu, req->rq_disk, part, sectors[rw], | 1561 | part_stat_add(cpu, part, sectors[rw], nr_bytes >> 9); |
1573 | nr_bytes >> 9, req->sector); | 1562 | part_stat_unlock(); |
1574 | disk_stat_unlock(); | ||
1575 | } | 1563 | } |
1576 | 1564 | ||
1577 | total_bytes = bio_nbytes = 0; | 1565 | total_bytes = bio_nbytes = 0; |
@@ -1758,19 +1746,15 @@ static void end_that_request_last(struct request *req, int error) | |||
1758 | struct hd_struct *part; | 1746 | struct hd_struct *part; |
1759 | int cpu; | 1747 | int cpu; |
1760 | 1748 | ||
1761 | cpu = disk_stat_lock(); | 1749 | cpu = part_stat_lock(); |
1762 | part = disk_map_sector_rcu(disk, req->sector); | 1750 | part = disk_map_sector_rcu(disk, req->sector); |
1763 | 1751 | ||
1764 | all_stat_inc(cpu, disk, part, ios[rw], req->sector); | 1752 | part_stat_inc(cpu, part, ios[rw]); |
1765 | all_stat_add(cpu, disk, part, ticks[rw], duration, req->sector); | 1753 | part_stat_add(cpu, part, ticks[rw], duration); |
1766 | disk_round_stats(cpu, disk); | 1754 | part_round_stats(cpu, part); |
1767 | disk->in_flight--; | 1755 | part_dec_in_flight(part); |
1768 | if (part) { | ||
1769 | part_round_stats(cpu, part); | ||
1770 | part->in_flight--; | ||
1771 | } | ||
1772 | 1756 | ||
1773 | disk_stat_unlock(); | 1757 | part_stat_unlock(); |
1774 | } | 1758 | } |
1775 | 1759 | ||
1776 | if (req->end_io) | 1760 | if (req->end_io) |
diff --git a/block/blk-merge.c b/block/blk-merge.c index d926a24bf1fd..c77196d55899 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -390,17 +390,13 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
390 | struct hd_struct *part; | 390 | struct hd_struct *part; |
391 | int cpu; | 391 | int cpu; |
392 | 392 | ||
393 | cpu = disk_stat_lock(); | 393 | cpu = part_stat_lock(); |
394 | part = disk_map_sector_rcu(req->rq_disk, req->sector); | 394 | part = disk_map_sector_rcu(req->rq_disk, req->sector); |
395 | 395 | ||
396 | disk_round_stats(cpu, req->rq_disk); | 396 | part_round_stats(cpu, part); |
397 | req->rq_disk->in_flight--; | 397 | part_dec_in_flight(part); |
398 | if (part) { | ||
399 | part_round_stats(cpu, part); | ||
400 | part->in_flight--; | ||
401 | } | ||
402 | 398 | ||
403 | disk_stat_unlock(); | 399 | part_stat_unlock(); |
404 | } | 400 | } |
405 | 401 | ||
406 | req->ioprio = ioprio_best(req->ioprio, next->ioprio); | 402 | req->ioprio = ioprio_best(req->ioprio, next->ioprio); |
diff --git a/block/genhd.c b/block/genhd.c index 06a252f2b967..e1cb96fb883e 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -176,7 +176,7 @@ EXPORT_SYMBOL_GPL(disk_part_iter_exit); | |||
176 | * while preemption is disabled. | 176 | * while preemption is disabled. |
177 | * | 177 | * |
178 | * RETURNS: | 178 | * RETURNS: |
179 | * Found partition on success, NULL if there's no matching partition. | 179 | * Found partition on success, part0 is returned if no partition matches |
180 | */ | 180 | */ |
181 | struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) | 181 | struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) |
182 | { | 182 | { |
@@ -189,7 +189,7 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) | |||
189 | sector < part->start_sect + part->nr_sects) | 189 | sector < part->start_sect + part->nr_sects) |
190 | return part; | 190 | return part; |
191 | } | 191 | } |
192 | return NULL; | 192 | return &disk->part0; |
193 | } | 193 | } |
194 | EXPORT_SYMBOL_GPL(disk_map_sector_rcu); | 194 | EXPORT_SYMBOL_GPL(disk_map_sector_rcu); |
195 | 195 | ||
@@ -580,24 +580,24 @@ void __init printk_all_partitions(void) | |||
580 | * numbers in hex - the same format as the root= | 580 | * numbers in hex - the same format as the root= |
581 | * option takes. | 581 | * option takes. |
582 | */ | 582 | */ |
583 | printk("%s %10llu %s", | 583 | disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0); |
584 | bdevt_str(disk_devt(disk), devt_buf), | 584 | while ((part = disk_part_iter_next(&piter))) { |
585 | (unsigned long long)get_capacity(disk) >> 1, | 585 | bool is_part0 = part == &disk->part0; |
586 | disk_name(disk, 0, name_buf)); | ||
587 | if (disk->driverfs_dev != NULL && | ||
588 | disk->driverfs_dev->driver != NULL) | ||
589 | printk(" driver: %s\n", | ||
590 | disk->driverfs_dev->driver->name); | ||
591 | else | ||
592 | printk(" (driver?)\n"); | ||
593 | 586 | ||
594 | /* now show the partitions */ | 587 | printk("%s%s %10llu %s", is_part0 ? "" : " ", |
595 | disk_part_iter_init(&piter, disk, 0); | ||
596 | while ((part = disk_part_iter_next(&piter))) | ||
597 | printk(" %s %10llu %s\n", | ||
598 | bdevt_str(part_devt(part), devt_buf), | 588 | bdevt_str(part_devt(part), devt_buf), |
599 | (unsigned long long)part->nr_sects >> 1, | 589 | (unsigned long long)part->nr_sects >> 1, |
600 | disk_name(disk, part->partno, name_buf)); | 590 | disk_name(disk, part->partno, name_buf)); |
591 | if (is_part0) { | ||
592 | if (disk->driverfs_dev != NULL && | ||
593 | disk->driverfs_dev->driver != NULL) | ||
594 | printk(" driver: %s\n", | ||
595 | disk->driverfs_dev->driver->name); | ||
596 | else | ||
597 | printk(" (driver?)\n"); | ||
598 | } else | ||
599 | printk("\n"); | ||
600 | } | ||
601 | disk_part_iter_exit(&piter); | 601 | disk_part_iter_exit(&piter); |
602 | } | 602 | } |
603 | class_dev_iter_exit(&iter); | 603 | class_dev_iter_exit(&iter); |
@@ -674,12 +674,7 @@ static int show_partition(struct seq_file *seqf, void *v) | |||
674 | return 0; | 674 | return 0; |
675 | 675 | ||
676 | /* show the full disk and all non-0 size partitions of it */ | 676 | /* show the full disk and all non-0 size partitions of it */ |
677 | seq_printf(seqf, "%4d %7d %10llu %s\n", | 677 | disk_part_iter_init(&piter, sgp, DISK_PITER_INCL_PART0); |
678 | MAJOR(disk_devt(sgp)), MINOR(disk_devt(sgp)), | ||
679 | (unsigned long long)get_capacity(sgp) >> 1, | ||
680 | disk_name(sgp, 0, buf)); | ||
681 | |||
682 | disk_part_iter_init(&piter, sgp, 0); | ||
683 | while ((part = disk_part_iter_next(&piter))) | 678 | while ((part = disk_part_iter_next(&piter))) |
684 | seq_printf(seqf, "%4d %7d %10llu %s\n", | 679 | seq_printf(seqf, "%4d %7d %10llu %s\n", |
685 | MAJOR(part_devt(part)), MINOR(part_devt(part)), | 680 | MAJOR(part_devt(part)), MINOR(part_devt(part)), |
@@ -768,40 +763,13 @@ static ssize_t disk_capability_show(struct device *dev, | |||
768 | return sprintf(buf, "%x\n", disk->flags); | 763 | return sprintf(buf, "%x\n", disk->flags); |
769 | } | 764 | } |
770 | 765 | ||
771 | static ssize_t disk_stat_show(struct device *dev, | ||
772 | struct device_attribute *attr, char *buf) | ||
773 | { | ||
774 | struct gendisk *disk = dev_to_disk(dev); | ||
775 | int cpu; | ||
776 | |||
777 | cpu = disk_stat_lock(); | ||
778 | disk_round_stats(cpu, disk); | ||
779 | disk_stat_unlock(); | ||
780 | return sprintf(buf, | ||
781 | "%8lu %8lu %8llu %8u " | ||
782 | "%8lu %8lu %8llu %8u " | ||
783 | "%8u %8u %8u" | ||
784 | "\n", | ||
785 | disk_stat_read(disk, ios[READ]), | ||
786 | disk_stat_read(disk, merges[READ]), | ||
787 | (unsigned long long)disk_stat_read(disk, sectors[READ]), | ||
788 | jiffies_to_msecs(disk_stat_read(disk, ticks[READ])), | ||
789 | disk_stat_read(disk, ios[WRITE]), | ||
790 | disk_stat_read(disk, merges[WRITE]), | ||
791 | (unsigned long long)disk_stat_read(disk, sectors[WRITE]), | ||
792 | jiffies_to_msecs(disk_stat_read(disk, ticks[WRITE])), | ||
793 | disk->in_flight, | ||
794 | jiffies_to_msecs(disk_stat_read(disk, io_ticks)), | ||
795 | jiffies_to_msecs(disk_stat_read(disk, time_in_queue))); | ||
796 | } | ||
797 | |||
798 | static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); | 766 | static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); |
799 | static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL); | 767 | static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL); |
800 | static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); | 768 | static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); |
801 | static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL); | 769 | static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL); |
802 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | 770 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); |
803 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); | 771 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); |
804 | static DEVICE_ATTR(stat, S_IRUGO, disk_stat_show, NULL); | 772 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); |
805 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 773 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
806 | static struct device_attribute dev_attr_fail = | 774 | static struct device_attribute dev_attr_fail = |
807 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); | 775 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); |
@@ -836,7 +804,7 @@ static void disk_release(struct device *dev) | |||
836 | 804 | ||
837 | kfree(disk->random); | 805 | kfree(disk->random); |
838 | kfree(disk->__part); | 806 | kfree(disk->__part); |
839 | free_disk_stats(disk); | 807 | free_part_stats(&disk->part0); |
840 | kfree(disk); | 808 | kfree(disk); |
841 | } | 809 | } |
842 | struct class block_class = { | 810 | struct class block_class = { |
@@ -873,28 +841,11 @@ static int diskstats_show(struct seq_file *seqf, void *v) | |||
873 | "\n\n"); | 841 | "\n\n"); |
874 | */ | 842 | */ |
875 | 843 | ||
876 | cpu = disk_stat_lock(); | 844 | disk_part_iter_init(&piter, gp, DISK_PITER_INCL_PART0); |
877 | disk_round_stats(cpu, gp); | ||
878 | disk_stat_unlock(); | ||
879 | seq_printf(seqf, "%4d %7d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n", | ||
880 | MAJOR(disk_devt(gp)), MINOR(disk_devt(gp)), | ||
881 | disk_name(gp, 0, buf), | ||
882 | disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]), | ||
883 | (unsigned long long)disk_stat_read(gp, sectors[0]), | ||
884 | jiffies_to_msecs(disk_stat_read(gp, ticks[0])), | ||
885 | disk_stat_read(gp, ios[1]), disk_stat_read(gp, merges[1]), | ||
886 | (unsigned long long)disk_stat_read(gp, sectors[1]), | ||
887 | jiffies_to_msecs(disk_stat_read(gp, ticks[1])), | ||
888 | gp->in_flight, | ||
889 | jiffies_to_msecs(disk_stat_read(gp, io_ticks)), | ||
890 | jiffies_to_msecs(disk_stat_read(gp, time_in_queue))); | ||
891 | |||
892 | /* now show all non-0 size partitions of it */ | ||
893 | disk_part_iter_init(&piter, gp, 0); | ||
894 | while ((hd = disk_part_iter_next(&piter))) { | 845 | while ((hd = disk_part_iter_next(&piter))) { |
895 | cpu = disk_stat_lock(); | 846 | cpu = part_stat_lock(); |
896 | part_round_stats(cpu, hd); | 847 | part_round_stats(cpu, hd); |
897 | disk_stat_unlock(); | 848 | part_stat_unlock(); |
898 | seq_printf(seqf, "%4d %7d %s %lu %lu %llu " | 849 | seq_printf(seqf, "%4d %7d %s %lu %lu %llu " |
899 | "%u %lu %lu %llu %u %u %u %u\n", | 850 | "%u %lu %lu %llu %u %u %u %u\n", |
900 | MAJOR(part_devt(hd)), MINOR(part_devt(hd)), | 851 | MAJOR(part_devt(hd)), MINOR(part_devt(hd)), |
@@ -1000,7 +951,7 @@ struct gendisk *alloc_disk_ext_node(int minors, int ext_minors, int node_id) | |||
1000 | int tot_minors = minors + ext_minors; | 951 | int tot_minors = minors + ext_minors; |
1001 | int size = tot_minors * sizeof(struct hd_struct *); | 952 | int size = tot_minors * sizeof(struct hd_struct *); |
1002 | 953 | ||
1003 | if (!init_disk_stats(disk)) { | 954 | if (!init_part_stats(&disk->part0)) { |
1004 | kfree(disk); | 955 | kfree(disk); |
1005 | return NULL; | 956 | return NULL; |
1006 | } | 957 | } |
@@ -1008,7 +959,7 @@ struct gendisk *alloc_disk_ext_node(int minors, int ext_minors, int node_id) | |||
1008 | disk->__part = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, | 959 | disk->__part = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, |
1009 | node_id); | 960 | node_id); |
1010 | if (!disk->__part) { | 961 | if (!disk->__part) { |
1011 | free_disk_stats(disk); | 962 | free_part_stats(&disk->part0); |
1012 | kfree(disk); | 963 | kfree(disk); |
1013 | return NULL; | 964 | return NULL; |
1014 | } | 965 | } |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 934800f979c9..961d29a53cab 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -758,15 +758,15 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector | |||
758 | struct hd_struct *part; | 758 | struct hd_struct *part; |
759 | int cpu; | 759 | int cpu; |
760 | 760 | ||
761 | cpu = disk_stat_lock(); | 761 | cpu = part_stat_lock(); |
762 | part = disk_map_sector_rcu(disk, sector); | 762 | part = disk_map_sector_rcu(disk, sector); |
763 | 763 | ||
764 | all_stat_inc(cpu, disk, part, ios[rw], sector); | 764 | part_stat_inc(cpu, part, ios[rw]); |
765 | all_stat_add(cpu, disk, part, ticks[rw], duration, sector); | 765 | part_stat_add(cpu, part, ticks[rw], duration); |
766 | all_stat_add(cpu, disk, part, sectors[rw], n_sect, sector); | 766 | part_stat_add(cpu, part, sectors[rw], n_sect); |
767 | all_stat_add(cpu, disk, part, io_ticks, duration, sector); | 767 | part_stat_add(cpu, part, io_ticks, duration); |
768 | 768 | ||
769 | disk_stat_unlock(); | 769 | part_stat_unlock(); |
770 | } | 770 | } |
771 | 771 | ||
772 | void | 772 | void |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 637806695bb9..327de03a5bdf 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -381,10 +381,10 @@ static void start_io_acct(struct dm_io *io) | |||
381 | 381 | ||
382 | io->start_time = jiffies; | 382 | io->start_time = jiffies; |
383 | 383 | ||
384 | cpu = disk_stat_lock(); | 384 | cpu = part_stat_lock(); |
385 | disk_round_stats(cpu, dm_disk(md)); | 385 | part_round_stats(cpu, &dm_disk(md)->part0); |
386 | disk_stat_unlock(); | 386 | part_stat_unlock(); |
387 | dm_disk(md)->in_flight = atomic_inc_return(&md->pending); | 387 | dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending); |
388 | } | 388 | } |
389 | 389 | ||
390 | static int end_io_acct(struct dm_io *io) | 390 | static int end_io_acct(struct dm_io *io) |
@@ -395,12 +395,13 @@ static int end_io_acct(struct dm_io *io) | |||
395 | int pending, cpu; | 395 | int pending, cpu; |
396 | int rw = bio_data_dir(bio); | 396 | int rw = bio_data_dir(bio); |
397 | 397 | ||
398 | cpu = disk_stat_lock(); | 398 | cpu = part_stat_lock(); |
399 | disk_round_stats(cpu, dm_disk(md)); | 399 | part_round_stats(cpu, &dm_disk(md)->part0); |
400 | disk_stat_add(cpu, dm_disk(md), ticks[rw], duration); | 400 | part_stat_add(cpu, &dm_disk(md)->part0, ticks[rw], duration); |
401 | disk_stat_unlock(); | 401 | part_stat_unlock(); |
402 | 402 | ||
403 | dm_disk(md)->in_flight = pending = atomic_dec_return(&md->pending); | 403 | dm_disk(md)->part0.in_flight = pending = |
404 | atomic_dec_return(&md->pending); | ||
404 | 405 | ||
405 | return !pending; | 406 | return !pending; |
406 | } | 407 | } |
@@ -899,10 +900,10 @@ static int dm_request(struct request_queue *q, struct bio *bio) | |||
899 | 900 | ||
900 | down_read(&md->io_lock); | 901 | down_read(&md->io_lock); |
901 | 902 | ||
902 | cpu = disk_stat_lock(); | 903 | cpu = part_stat_lock(); |
903 | disk_stat_inc(cpu, dm_disk(md), ios[rw]); | 904 | part_stat_inc(cpu, &dm_disk(md)->part0, ios[rw]); |
904 | disk_stat_add(cpu, dm_disk(md), sectors[rw], bio_sectors(bio)); | 905 | part_stat_add(cpu, &dm_disk(md)->part0, sectors[rw], bio_sectors(bio)); |
905 | disk_stat_unlock(); | 906 | part_stat_unlock(); |
906 | 907 | ||
907 | /* | 908 | /* |
908 | * If we're suspended we have to queue | 909 | * If we're suspended we have to queue |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 00cbc8e47294..c80ea90593d3 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -325,10 +325,11 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
325 | return 0; | 325 | return 0; |
326 | } | 326 | } |
327 | 327 | ||
328 | cpu = disk_stat_lock(); | 328 | cpu = part_stat_lock(); |
329 | disk_stat_inc(cpu, mddev->gendisk, ios[rw]); | 329 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
330 | disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio)); | 330 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], |
331 | disk_stat_unlock(); | 331 | bio_sectors(bio)); |
332 | part_stat_unlock(); | ||
332 | 333 | ||
333 | tmp_dev = which_dev(mddev, bio->bi_sector); | 334 | tmp_dev = which_dev(mddev, bio->bi_sector); |
334 | block = bio->bi_sector >> 1; | 335 | block = bio->bi_sector >> 1; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 2bd9cf416123..0a3a4bdcd4af 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -5546,8 +5546,8 @@ static int is_mddev_idle(mddev_t *mddev) | |||
5546 | rcu_read_lock(); | 5546 | rcu_read_lock(); |
5547 | rdev_for_each_rcu(rdev, mddev) { | 5547 | rdev_for_each_rcu(rdev, mddev) { |
5548 | struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; | 5548 | struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; |
5549 | curr_events = disk_stat_read(disk, sectors[0]) + | 5549 | curr_events = part_stat_read(&disk->part0, sectors[0]) + |
5550 | disk_stat_read(disk, sectors[1]) - | 5550 | part_stat_read(&disk->part0, sectors[1]) - |
5551 | atomic_read(&disk->sync_io); | 5551 | atomic_read(&disk->sync_io); |
5552 | /* sync IO will cause sync_io to increase before the disk_stats | 5552 | /* sync IO will cause sync_io to increase before the disk_stats |
5553 | * as sync_io is counted when a request starts, and | 5553 | * as sync_io is counted when a request starts, and |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 182f5a94cdc5..8bb8794129b3 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -159,10 +159,11 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio) | |||
159 | mp_bh->master_bio = bio; | 159 | mp_bh->master_bio = bio; |
160 | mp_bh->mddev = mddev; | 160 | mp_bh->mddev = mddev; |
161 | 161 | ||
162 | cpu = disk_stat_lock(); | 162 | cpu = part_stat_lock(); |
163 | disk_stat_inc(cpu, mddev->gendisk, ios[rw]); | 163 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
164 | disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio)); | 164 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], |
165 | disk_stat_unlock(); | 165 | bio_sectors(bio)); |
166 | part_stat_unlock(); | ||
166 | 167 | ||
167 | mp_bh->path = multipath_map(conf); | 168 | mp_bh->path = multipath_map(conf); |
168 | if (mp_bh->path < 0) { | 169 | if (mp_bh->path < 0) { |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e26030fa59ab..f52f442a735f 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -406,10 +406,11 @@ static int raid0_make_request (struct request_queue *q, struct bio *bio) | |||
406 | return 0; | 406 | return 0; |
407 | } | 407 | } |
408 | 408 | ||
409 | cpu = disk_stat_lock(); | 409 | cpu = part_stat_lock(); |
410 | disk_stat_inc(cpu, mddev->gendisk, ios[rw]); | 410 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
411 | disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio)); | 411 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], |
412 | disk_stat_unlock(); | 412 | bio_sectors(bio)); |
413 | part_stat_unlock(); | ||
413 | 414 | ||
414 | chunk_size = mddev->chunk_size >> 10; | 415 | chunk_size = mddev->chunk_size >> 10; |
415 | chunk_sects = mddev->chunk_size >> 9; | 416 | chunk_sects = mddev->chunk_size >> 9; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index babb13036f93..b9764429d856 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -804,10 +804,11 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
804 | 804 | ||
805 | bitmap = mddev->bitmap; | 805 | bitmap = mddev->bitmap; |
806 | 806 | ||
807 | cpu = disk_stat_lock(); | 807 | cpu = part_stat_lock(); |
808 | disk_stat_inc(cpu, mddev->gendisk, ios[rw]); | 808 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
809 | disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio)); | 809 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], |
810 | disk_stat_unlock(); | 810 | bio_sectors(bio)); |
811 | part_stat_unlock(); | ||
811 | 812 | ||
812 | /* | 813 | /* |
813 | * make_request() can abort the operation when READA is being | 814 | * make_request() can abort the operation when READA is being |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 5ec80da0a9d7..5f990133f5ef 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -844,10 +844,11 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
844 | */ | 844 | */ |
845 | wait_barrier(conf); | 845 | wait_barrier(conf); |
846 | 846 | ||
847 | cpu = disk_stat_lock(); | 847 | cpu = part_stat_lock(); |
848 | disk_stat_inc(cpu, mddev->gendisk, ios[rw]); | 848 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
849 | disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio)); | 849 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], |
850 | disk_stat_unlock(); | 850 | bio_sectors(bio)); |
851 | part_stat_unlock(); | ||
851 | 852 | ||
852 | r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO); | 853 | r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO); |
853 | 854 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 5899f211515f..ae16794bef20 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3396,10 +3396,11 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3396 | 3396 | ||
3397 | md_write_start(mddev, bi); | 3397 | md_write_start(mddev, bi); |
3398 | 3398 | ||
3399 | cpu = disk_stat_lock(); | 3399 | cpu = part_stat_lock(); |
3400 | disk_stat_inc(cpu, mddev->gendisk, ios[rw]); | 3400 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
3401 | disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bi)); | 3401 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], |
3402 | disk_stat_unlock(); | 3402 | bio_sectors(bi)); |
3403 | part_stat_unlock(); | ||
3403 | 3404 | ||
3404 | if (rw == READ && | 3405 | if (rw == READ && |
3405 | mddev->reshape_position == MaxSector && | 3406 | mddev->reshape_position == MaxSector && |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 60592d9f43b6..f517869e8d10 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -210,15 +210,15 @@ ssize_t part_size_show(struct device *dev, | |||
210 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); | 210 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); |
211 | } | 211 | } |
212 | 212 | ||
213 | static ssize_t part_stat_show(struct device *dev, | 213 | ssize_t part_stat_show(struct device *dev, |
214 | struct device_attribute *attr, char *buf) | 214 | struct device_attribute *attr, char *buf) |
215 | { | 215 | { |
216 | struct hd_struct *p = dev_to_part(dev); | 216 | struct hd_struct *p = dev_to_part(dev); |
217 | int cpu; | 217 | int cpu; |
218 | 218 | ||
219 | cpu = disk_stat_lock(); | 219 | cpu = part_stat_lock(); |
220 | part_round_stats(cpu, p); | 220 | part_round_stats(cpu, p); |
221 | disk_stat_unlock(); | 221 | part_stat_unlock(); |
222 | return sprintf(buf, | 222 | return sprintf(buf, |
223 | "%8lu %8lu %8llu %8u " | 223 | "%8lu %8lu %8llu %8u " |
224 | "%8lu %8lu %8llu %8u " | 224 | "%8lu %8lu %8llu %8u " |
@@ -575,8 +575,8 @@ void del_gendisk(struct gendisk *disk) | |||
575 | set_capacity(disk, 0); | 575 | set_capacity(disk, 0); |
576 | disk->flags &= ~GENHD_FL_UP; | 576 | disk->flags &= ~GENHD_FL_UP; |
577 | unlink_gendisk(disk); | 577 | unlink_gendisk(disk); |
578 | disk_stat_set_all(disk, 0); | 578 | part_stat_set_all(&disk->part0, 0); |
579 | disk->stamp = 0; | 579 | disk->part0.stamp = 0; |
580 | 580 | ||
581 | kobject_put(disk->part0.holder_dir); | 581 | kobject_put(disk->part0.holder_dir); |
582 | kobject_put(disk->slave_dir); | 582 | kobject_put(disk->slave_dir); |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 3d15b42dc352..c90e1b4fbe5a 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -145,13 +145,6 @@ struct gendisk { | |||
145 | struct timer_rand_state *random; | 145 | struct timer_rand_state *random; |
146 | 146 | ||
147 | atomic_t sync_io; /* RAID */ | 147 | atomic_t sync_io; /* RAID */ |
148 | unsigned long stamp; | ||
149 | int in_flight; | ||
150 | #ifdef CONFIG_SMP | ||
151 | struct disk_stats *dkstats; | ||
152 | #else | ||
153 | struct disk_stats dkstats; | ||
154 | #endif | ||
155 | struct work_struct async_notify; | 148 | struct work_struct async_notify; |
156 | #ifdef CONFIG_BLK_DEV_INTEGRITY | 149 | #ifdef CONFIG_BLK_DEV_INTEGRITY |
157 | struct blk_integrity *integrity; | 150 | struct blk_integrity *integrity; |
@@ -232,46 +225,18 @@ extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, | |||
232 | * internal use only. | 225 | * internal use only. |
233 | */ | 226 | */ |
234 | #ifdef CONFIG_SMP | 227 | #ifdef CONFIG_SMP |
235 | #define disk_stat_lock() ({ rcu_read_lock(); get_cpu(); }) | 228 | #define part_stat_lock() ({ rcu_read_lock(); get_cpu(); }) |
236 | #define disk_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) | 229 | #define part_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) |
237 | |||
238 | #define disk_stat_add(cpu, gendiskp, field, addnd) \ | ||
239 | (per_cpu_ptr(gendiskp->dkstats, cpu)->field += addnd) | ||
240 | |||
241 | #define disk_stat_read(gendiskp, field) \ | ||
242 | ({ \ | ||
243 | typeof(gendiskp->dkstats->field) res = 0; \ | ||
244 | int i; \ | ||
245 | for_each_possible_cpu(i) \ | ||
246 | res += per_cpu_ptr(gendiskp->dkstats, i)->field; \ | ||
247 | res; \ | ||
248 | }) | ||
249 | |||
250 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) | ||
251 | { | ||
252 | int i; | ||
253 | |||
254 | for_each_possible_cpu(i) | ||
255 | memset(per_cpu_ptr(gendiskp->dkstats, i), value, | ||
256 | sizeof(struct disk_stats)); | ||
257 | } | ||
258 | 230 | ||
259 | #define part_stat_add(cpu, part, field, addnd) \ | 231 | #define __part_stat_add(cpu, part, field, addnd) \ |
260 | (per_cpu_ptr(part->dkstats, cpu)->field += addnd) | 232 | (per_cpu_ptr((part)->dkstats, (cpu))->field += (addnd)) |
261 | |||
262 | #define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ | ||
263 | ({ \ | ||
264 | if (part) \ | ||
265 | part_stat_add(cpu, part, field, addnd); \ | ||
266 | disk_stat_add(cpu, gendiskp, field, addnd); \ | ||
267 | }) | ||
268 | 233 | ||
269 | #define part_stat_read(part, field) \ | 234 | #define part_stat_read(part, field) \ |
270 | ({ \ | 235 | ({ \ |
271 | typeof(part->dkstats->field) res = 0; \ | 236 | typeof((part)->dkstats->field) res = 0; \ |
272 | int i; \ | 237 | int i; \ |
273 | for_each_possible_cpu(i) \ | 238 | for_each_possible_cpu(i) \ |
274 | res += per_cpu_ptr(part->dkstats, i)->field; \ | 239 | res += per_cpu_ptr((part)->dkstats, i)->field; \ |
275 | res; \ | 240 | res; \ |
276 | }) | 241 | }) |
277 | 242 | ||
@@ -284,109 +249,73 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) | |||
284 | sizeof(struct disk_stats)); | 249 | sizeof(struct disk_stats)); |
285 | } | 250 | } |
286 | 251 | ||
287 | #else /* !CONFIG_SMP */ | 252 | static inline int init_part_stats(struct hd_struct *part) |
288 | #define disk_stat_lock() ({ rcu_read_lock(); 0; }) | ||
289 | #define disk_stat_unlock() rcu_read_unlock() | ||
290 | |||
291 | #define disk_stat_add(cpu, gendiskp, field, addnd) \ | ||
292 | (gendiskp->dkstats.field += addnd) | ||
293 | #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) | ||
294 | |||
295 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) | ||
296 | { | 253 | { |
297 | memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); | 254 | part->dkstats = alloc_percpu(struct disk_stats); |
255 | if (!part->dkstats) | ||
256 | return 0; | ||
257 | return 1; | ||
298 | } | 258 | } |
299 | 259 | ||
300 | #define part_stat_add(cpu, part, field, addnd) \ | 260 | static inline void free_part_stats(struct hd_struct *part) |
301 | (part->dkstats.field += addnd) | ||
302 | |||
303 | #define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ | ||
304 | ({ \ | ||
305 | if (part) \ | ||
306 | part_stat_add(cpu, part, field, addnd); \ | ||
307 | disk_stat_add(cpu, gendiskp, field, addnd); \ | ||
308 | }) | ||
309 | |||
310 | #define part_stat_read(part, field) (part->dkstats.field) | ||
311 | |||
312 | static inline void part_stat_set_all(struct hd_struct *part, int value) | ||
313 | { | 261 | { |
314 | memset(&part->dkstats, value, sizeof(struct disk_stats)); | 262 | free_percpu(part->dkstats); |
315 | } | 263 | } |
316 | 264 | ||
317 | #endif /* CONFIG_SMP */ | 265 | #else /* !CONFIG_SMP */ |
318 | 266 | #define part_stat_lock() ({ rcu_read_lock(); 0; }) | |
319 | #define disk_stat_dec(cpu, gendiskp, field) \ | 267 | #define part_stat_unlock() rcu_read_unlock() |
320 | disk_stat_add(cpu, gendiskp, field, -1) | ||
321 | #define disk_stat_inc(cpu, gendiskp, field) \ | ||
322 | disk_stat_add(cpu, gendiskp, field, 1) | ||
323 | #define disk_stat_sub(cpu, gendiskp, field, subnd) \ | ||
324 | disk_stat_add(cpu, gendiskp, field, -subnd) | ||
325 | |||
326 | #define part_stat_dec(cpu, gendiskp, field) \ | ||
327 | part_stat_add(cpu, gendiskp, field, -1) | ||
328 | #define part_stat_inc(cpu, gendiskp, field) \ | ||
329 | part_stat_add(cpu, gendiskp, field, 1) | ||
330 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ | ||
331 | part_stat_add(cpu, gendiskp, field, -subnd) | ||
332 | 268 | ||
333 | #define all_stat_dec(cpu, gendiskp, field, sector) \ | 269 | #define __part_stat_add(cpu, part, field, addnd) \ |
334 | all_stat_add(cpu, gendiskp, field, -1, sector) | 270 | ((part)->dkstats.field += addnd) |
335 | #define all_stat_inc(cpu, gendiskp, part, field, sector) \ | ||
336 | all_stat_add(cpu, gendiskp, part, field, 1, sector) | ||
337 | #define all_stat_sub(cpu, gendiskp, part, field, subnd, sector) \ | ||
338 | all_stat_add(cpu, gendiskp, part, field, -subnd, sector) | ||
339 | 271 | ||
340 | /* Inlines to alloc and free disk stats in struct gendisk */ | 272 | #define part_stat_read(part, field) ((part)->dkstats.field) |
341 | #ifdef CONFIG_SMP | ||
342 | static inline int init_disk_stats(struct gendisk *disk) | ||
343 | { | ||
344 | disk->dkstats = alloc_percpu(struct disk_stats); | ||
345 | if (!disk->dkstats) | ||
346 | return 0; | ||
347 | return 1; | ||
348 | } | ||
349 | 273 | ||
350 | static inline void free_disk_stats(struct gendisk *disk) | 274 | static inline void part_stat_set_all(struct hd_struct *part, int value) |
351 | { | 275 | { |
352 | free_percpu(disk->dkstats); | 276 | memset(&part->dkstats, value, sizeof(struct disk_stats)); |
353 | } | 277 | } |
354 | 278 | ||
355 | static inline int init_part_stats(struct hd_struct *part) | 279 | static inline int init_part_stats(struct hd_struct *part) |
356 | { | 280 | { |
357 | part->dkstats = alloc_percpu(struct disk_stats); | ||
358 | if (!part->dkstats) | ||
359 | return 0; | ||
360 | return 1; | 281 | return 1; |
361 | } | 282 | } |
362 | 283 | ||
363 | static inline void free_part_stats(struct hd_struct *part) | 284 | static inline void free_part_stats(struct hd_struct *part) |
364 | { | 285 | { |
365 | free_percpu(part->dkstats); | ||
366 | } | 286 | } |
367 | 287 | ||
368 | #else /* CONFIG_SMP */ | 288 | #endif /* CONFIG_SMP */ |
369 | static inline int init_disk_stats(struct gendisk *disk) | ||
370 | { | ||
371 | return 1; | ||
372 | } | ||
373 | 289 | ||
374 | static inline void free_disk_stats(struct gendisk *disk) | 290 | #define part_stat_add(cpu, part, field, addnd) do { \ |
375 | { | 291 | __part_stat_add((cpu), (part), field, addnd); \ |
376 | } | 292 | if ((part)->partno) \ |
293 | __part_stat_add((cpu), &part_to_disk((part))->part0, \ | ||
294 | field, addnd); \ | ||
295 | } while (0) | ||
377 | 296 | ||
378 | static inline int init_part_stats(struct hd_struct *part) | 297 | #define part_stat_dec(cpu, gendiskp, field) \ |
298 | part_stat_add(cpu, gendiskp, field, -1) | ||
299 | #define part_stat_inc(cpu, gendiskp, field) \ | ||
300 | part_stat_add(cpu, gendiskp, field, 1) | ||
301 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ | ||
302 | part_stat_add(cpu, gendiskp, field, -subnd) | ||
303 | |||
304 | static inline void part_inc_in_flight(struct hd_struct *part) | ||
379 | { | 305 | { |
380 | return 1; | 306 | part->in_flight++; |
307 | if (part->partno) | ||
308 | part_to_disk(part)->part0.in_flight++; | ||
381 | } | 309 | } |
382 | 310 | ||
383 | static inline void free_part_stats(struct hd_struct *part) | 311 | static inline void part_dec_in_flight(struct hd_struct *part) |
384 | { | 312 | { |
313 | part->in_flight--; | ||
314 | if (part->partno) | ||
315 | part_to_disk(part)->part0.in_flight--; | ||
385 | } | 316 | } |
386 | #endif /* CONFIG_SMP */ | ||
387 | 317 | ||
388 | /* drivers/block/ll_rw_blk.c */ | 318 | /* drivers/block/ll_rw_blk.c */ |
389 | extern void disk_round_stats(int cpu, struct gendisk *disk); | ||
390 | extern void part_round_stats(int cpu, struct hd_struct *part); | 319 | extern void part_round_stats(int cpu, struct hd_struct *part); |
391 | 320 | ||
392 | /* drivers/block/genhd.c */ | 321 | /* drivers/block/genhd.c */ |
@@ -595,6 +524,8 @@ extern void blk_unregister_region(dev_t devt, unsigned long range); | |||
595 | 524 | ||
596 | extern ssize_t part_size_show(struct device *dev, | 525 | extern ssize_t part_size_show(struct device *dev, |
597 | struct device_attribute *attr, char *buf); | 526 | struct device_attribute *attr, char *buf); |
527 | extern ssize_t part_stat_show(struct device *dev, | ||
528 | struct device_attribute *attr, char *buf); | ||
598 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 529 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
599 | extern ssize_t part_fail_show(struct device *dev, | 530 | extern ssize_t part_fail_show(struct device *dev, |
600 | struct device_attribute *attr, char *buf); | 531 | struct device_attribute *attr, char *buf); |