diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 12:42:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 12:42:46 -0500 |
commit | 03054de1e0b90b33e9974107d84dabd2509f5898 (patch) | |
tree | a85e92d5387d94ef9e3d10bf11467136c681ad04 /block | |
parent | b5eb9513f7c1bee862ada22bf1489f53752686bd (diff) | |
parent | 0e53c2be0495afa97c6b0d06397adcbff9c65347 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
Enhanced partition statistics: documentation update
Enhanced partition statistics: remove old partition statistics
Enhanced partition statistics: procfs
Enhanced partition statistics: sysfs
Enhanced partition statistics: aoe fix
Enhanced partition statistics: update partition statitics
Enhanced partition statistics: core statistics
block: fixup rq_init() a bit
Manually fixed conflict in drivers/block/aoe/aoecmd.c due to statistics
support.
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 61 | ||||
-rw-r--r-- | block/blk-merge.c | 6 | ||||
-rw-r--r-- | block/genhd.c | 28 |
3 files changed, 75 insertions, 20 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 4afb39c82339..e9754dc98ec4 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -60,10 +60,15 @@ static void drive_stat_acct(struct request *rq, int new_io) | |||
60 | return; | 60 | return; |
61 | 61 | ||
62 | if (!new_io) { | 62 | if (!new_io) { |
63 | __disk_stat_inc(rq->rq_disk, merges[rw]); | 63 | __all_stat_inc(rq->rq_disk, merges[rw], rq->sector); |
64 | } else { | 64 | } else { |
65 | struct hd_struct *part = get_part(rq->rq_disk, rq->sector); | ||
65 | disk_round_stats(rq->rq_disk); | 66 | disk_round_stats(rq->rq_disk); |
66 | rq->rq_disk->in_flight++; | 67 | rq->rq_disk->in_flight++; |
68 | if (part) { | ||
69 | part_round_stats(part); | ||
70 | part->in_flight++; | ||
71 | } | ||
67 | } | 72 | } |
68 | } | 73 | } |
69 | 74 | ||
@@ -102,27 +107,38 @@ struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev) | |||
102 | } | 107 | } |
103 | EXPORT_SYMBOL(blk_get_backing_dev_info); | 108 | EXPORT_SYMBOL(blk_get_backing_dev_info); |
104 | 109 | ||
110 | /* | ||
111 | * We can't just memset() the structure, since the allocation path | ||
112 | * already stored some information in the request. | ||
113 | */ | ||
105 | void rq_init(struct request_queue *q, struct request *rq) | 114 | void rq_init(struct request_queue *q, struct request *rq) |
106 | { | 115 | { |
107 | INIT_LIST_HEAD(&rq->queuelist); | 116 | INIT_LIST_HEAD(&rq->queuelist); |
108 | INIT_LIST_HEAD(&rq->donelist); | 117 | INIT_LIST_HEAD(&rq->donelist); |
109 | 118 | rq->q = q; | |
110 | rq->errors = 0; | 119 | rq->sector = rq->hard_sector = (sector_t) -1; |
120 | rq->nr_sectors = rq->hard_nr_sectors = 0; | ||
121 | rq->current_nr_sectors = rq->hard_cur_sectors = 0; | ||
111 | rq->bio = rq->biotail = NULL; | 122 | rq->bio = rq->biotail = NULL; |
112 | INIT_HLIST_NODE(&rq->hash); | 123 | INIT_HLIST_NODE(&rq->hash); |
113 | RB_CLEAR_NODE(&rq->rb_node); | 124 | RB_CLEAR_NODE(&rq->rb_node); |
125 | rq->rq_disk = NULL; | ||
126 | rq->nr_phys_segments = 0; | ||
127 | rq->nr_hw_segments = 0; | ||
114 | rq->ioprio = 0; | 128 | rq->ioprio = 0; |
129 | rq->special = NULL; | ||
115 | rq->buffer = NULL; | 130 | rq->buffer = NULL; |
131 | rq->tag = -1; | ||
132 | rq->errors = 0; | ||
116 | rq->ref_count = 1; | 133 | rq->ref_count = 1; |
117 | rq->q = q; | 134 | rq->cmd_len = 0; |
118 | rq->special = NULL; | 135 | memset(rq->cmd, 0, sizeof(rq->cmd)); |
119 | rq->data_len = 0; | 136 | rq->data_len = 0; |
137 | rq->sense_len = 0; | ||
120 | rq->data = NULL; | 138 | rq->data = NULL; |
121 | rq->nr_phys_segments = 0; | ||
122 | rq->sense = NULL; | 139 | rq->sense = NULL; |
123 | rq->end_io = NULL; | 140 | rq->end_io = NULL; |
124 | rq->end_io_data = NULL; | 141 | rq->end_io_data = NULL; |
125 | rq->completion_data = NULL; | ||
126 | rq->next_rq = NULL; | 142 | rq->next_rq = NULL; |
127 | } | 143 | } |
128 | 144 | ||
@@ -986,6 +1002,21 @@ void disk_round_stats(struct gendisk *disk) | |||
986 | } | 1002 | } |
987 | EXPORT_SYMBOL_GPL(disk_round_stats); | 1003 | EXPORT_SYMBOL_GPL(disk_round_stats); |
988 | 1004 | ||
1005 | void part_round_stats(struct hd_struct *part) | ||
1006 | { | ||
1007 | unsigned long now = jiffies; | ||
1008 | |||
1009 | if (now == part->stamp) | ||
1010 | return; | ||
1011 | |||
1012 | if (part->in_flight) { | ||
1013 | __part_stat_add(part, time_in_queue, | ||
1014 | part->in_flight * (now - part->stamp)); | ||
1015 | __part_stat_add(part, io_ticks, (now - part->stamp)); | ||
1016 | } | ||
1017 | part->stamp = now; | ||
1018 | } | ||
1019 | |||
989 | /* | 1020 | /* |
990 | * queue lock must be held | 1021 | * queue lock must be held |
991 | */ | 1022 | */ |
@@ -1188,10 +1219,6 @@ static inline void blk_partition_remap(struct bio *bio) | |||
1188 | 1219 | ||
1189 | if (bio_sectors(bio) && bdev != bdev->bd_contains) { | 1220 | if (bio_sectors(bio) && bdev != bdev->bd_contains) { |
1190 | struct hd_struct *p = bdev->bd_part; | 1221 | struct hd_struct *p = bdev->bd_part; |
1191 | const int rw = bio_data_dir(bio); | ||
1192 | |||
1193 | p->sectors[rw] += bio_sectors(bio); | ||
1194 | p->ios[rw]++; | ||
1195 | 1222 | ||
1196 | bio->bi_sector += p->start_sect; | 1223 | bio->bi_sector += p->start_sect; |
1197 | bio->bi_bdev = bdev->bd_contains; | 1224 | bio->bi_bdev = bdev->bd_contains; |
@@ -1519,7 +1546,8 @@ static int __end_that_request_first(struct request *req, int error, | |||
1519 | if (blk_fs_request(req) && req->rq_disk) { | 1546 | if (blk_fs_request(req) && req->rq_disk) { |
1520 | const int rw = rq_data_dir(req); | 1547 | const int rw = rq_data_dir(req); |
1521 | 1548 | ||
1522 | disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9); | 1549 | all_stat_add(req->rq_disk, sectors[rw], |
1550 | nr_bytes >> 9, req->sector); | ||
1523 | } | 1551 | } |
1524 | 1552 | ||
1525 | total_bytes = bio_nbytes = 0; | 1553 | total_bytes = bio_nbytes = 0; |
@@ -1704,11 +1732,16 @@ static void end_that_request_last(struct request *req, int error) | |||
1704 | if (disk && blk_fs_request(req) && req != &req->q->bar_rq) { | 1732 | if (disk && blk_fs_request(req) && req != &req->q->bar_rq) { |
1705 | unsigned long duration = jiffies - req->start_time; | 1733 | unsigned long duration = jiffies - req->start_time; |
1706 | const int rw = rq_data_dir(req); | 1734 | const int rw = rq_data_dir(req); |
1735 | struct hd_struct *part = get_part(disk, req->sector); | ||
1707 | 1736 | ||
1708 | __disk_stat_inc(disk, ios[rw]); | 1737 | __all_stat_inc(disk, ios[rw], req->sector); |
1709 | __disk_stat_add(disk, ticks[rw], duration); | 1738 | __all_stat_add(disk, ticks[rw], duration, req->sector); |
1710 | disk_round_stats(disk); | 1739 | disk_round_stats(disk); |
1711 | disk->in_flight--; | 1740 | disk->in_flight--; |
1741 | if (part) { | ||
1742 | part_round_stats(part); | ||
1743 | part->in_flight--; | ||
1744 | } | ||
1712 | } | 1745 | } |
1713 | 1746 | ||
1714 | if (req->end_io) | 1747 | if (req->end_io) |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 845ef8131108..d3b84bbb776a 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -454,8 +454,14 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
454 | elv_merge_requests(q, req, next); | 454 | elv_merge_requests(q, req, next); |
455 | 455 | ||
456 | if (req->rq_disk) { | 456 | if (req->rq_disk) { |
457 | struct hd_struct *part | ||
458 | = get_part(req->rq_disk, req->sector); | ||
457 | disk_round_stats(req->rq_disk); | 459 | disk_round_stats(req->rq_disk); |
458 | req->rq_disk->in_flight--; | 460 | req->rq_disk->in_flight--; |
461 | if (part) { | ||
462 | part_round_stats(part); | ||
463 | part->in_flight--; | ||
464 | } | ||
459 | } | 465 | } |
460 | 466 | ||
461 | req->ioprio = ioprio_best(req->ioprio, next->ioprio); | 467 | req->ioprio = ioprio_best(req->ioprio, next->ioprio); |
diff --git a/block/genhd.c b/block/genhd.c index de2ebb2fab43..53f2238e69c8 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -584,12 +584,28 @@ static int diskstats_show(struct seq_file *s, void *v) | |||
584 | for (n = 0; n < gp->minors - 1; n++) { | 584 | for (n = 0; n < gp->minors - 1; n++) { |
585 | struct hd_struct *hd = gp->part[n]; | 585 | struct hd_struct *hd = gp->part[n]; |
586 | 586 | ||
587 | if (hd && hd->nr_sects) | 587 | if (!hd || !hd->nr_sects) |
588 | seq_printf(s, "%4d %4d %s %u %u %u %u\n", | 588 | continue; |
589 | gp->major, n + gp->first_minor + 1, | 589 | |
590 | disk_name(gp, n + 1, buf), | 590 | preempt_disable(); |
591 | hd->ios[0], hd->sectors[0], | 591 | part_round_stats(hd); |
592 | hd->ios[1], hd->sectors[1]); | 592 | preempt_enable(); |
593 | seq_printf(s, "%4d %4d %s %lu %lu %llu " | ||
594 | "%u %lu %lu %llu %u %u %u %u\n", | ||
595 | gp->major, n + gp->first_minor + 1, | ||
596 | disk_name(gp, n + 1, buf), | ||
597 | part_stat_read(hd, ios[0]), | ||
598 | part_stat_read(hd, merges[0]), | ||
599 | (unsigned long long)part_stat_read(hd, sectors[0]), | ||
600 | jiffies_to_msecs(part_stat_read(hd, ticks[0])), | ||
601 | part_stat_read(hd, ios[1]), | ||
602 | part_stat_read(hd, merges[1]), | ||
603 | (unsigned long long)part_stat_read(hd, sectors[1]), | ||
604 | jiffies_to_msecs(part_stat_read(hd, ticks[1])), | ||
605 | hd->in_flight, | ||
606 | jiffies_to_msecs(part_stat_read(hd, io_ticks)), | ||
607 | jiffies_to_msecs(part_stat_read(hd, time_in_queue)) | ||
608 | ); | ||
593 | } | 609 | } |
594 | 610 | ||
595 | return 0; | 611 | return 0; |