Skip to content

Commit 074a7ac

Browse files
htejunJens Axboe
authored andcommitted
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 <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent eddb2e2 commit 074a7ac

File tree

14 files changed

+165
-296
lines changed

14 files changed

+165
-296
lines changed

block/blk-core.c

Lines changed: 34 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,17 @@ static void drive_stat_acct(struct request *rq, int new_io)
6161
if (!blk_fs_request(rq) || !rq->rq_disk)
6262
return;
6363

64-
cpu = disk_stat_lock();
64+
cpu = part_stat_lock();
6565
part = disk_map_sector_rcu(rq->rq_disk, rq->sector);
6666

6767
if (!new_io)
68-
all_stat_inc(cpu, rq->rq_disk, part, merges[rw], rq->sector);
68+
part_stat_inc(cpu, part, merges[rw]);
6969
else {
70-
disk_round_stats(cpu, rq->rq_disk);
71-
rq->rq_disk->in_flight++;
72-
if (part) {
73-
part_round_stats(cpu, part);
74-
part->in_flight++;
75-
}
70+
part_round_stats(cpu, part);
71+
part_inc_in_flight(part);
7672
}
7773

78-
disk_stat_unlock();
74+
part_stat_unlock();
7975
}
8076

8177
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)
983979
__elv_add_request(q, req, ELEVATOR_INSERT_SORT, 0);
984980
}
985981

986-
/*
987-
* disk_round_stats() - Round off the performance stats on a struct
982+
static void part_round_stats_single(int cpu, struct hd_struct *part,
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
988998
* disk_stats.
989999
*
9901000
* 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)
9981008
* /proc/diskstats. This accounts immediately for all queue usage up to
9991009
* the current jiffies and restarts the counters again.
10001010
*/
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-
10171011
void part_round_stats(int cpu, struct hd_struct *part)
10181012
{
10191013
unsigned long now = jiffies;
10201014

1021-
if (now == part->stamp)
1022-
return;
1023-
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;
1015+
if (part->partno)
1016+
part_round_stats_single(cpu, &part_to_disk(part)->part0, now);
1017+
part_round_stats_single(cpu, part, now);
10301018
}
1019+
EXPORT_SYMBOL_GPL(part_round_stats);
10311020

10321021
/*
10331022
* queue lock must be held
@@ -1567,11 +1556,10 @@ static int __end_that_request_first(struct request *req, int error,
15671556
struct hd_struct *part;
15681557
int cpu;
15691558

1570-
cpu = disk_stat_lock();
1559+
cpu = part_stat_lock();
15711560
part = disk_map_sector_rcu(req->rq_disk, req->sector);
1572-
all_stat_add(cpu, req->rq_disk, part, sectors[rw],
1573-
nr_bytes >> 9, req->sector);
1574-
disk_stat_unlock();
1561+
part_stat_add(cpu, part, sectors[rw], nr_bytes >> 9);
1562+
part_stat_unlock();
15751563
}
15761564

15771565
total_bytes = bio_nbytes = 0;
@@ -1758,19 +1746,15 @@ static void end_that_request_last(struct request *req, int error)
17581746
struct hd_struct *part;
17591747
int cpu;
17601748

1761-
cpu = disk_stat_lock();
1749+
cpu = part_stat_lock();
17621750
part = disk_map_sector_rcu(disk, req->sector);
17631751

1764-
all_stat_inc(cpu, disk, part, ios[rw], req->sector);
1765-
all_stat_add(cpu, disk, part, ticks[rw], duration, req->sector);
1766-
disk_round_stats(cpu, disk);
1767-
disk->in_flight--;
1768-
if (part) {
1769-
part_round_stats(cpu, part);
1770-
part->in_flight--;
1771-
}
1752+
part_stat_inc(cpu, part, ios[rw]);
1753+
part_stat_add(cpu, part, ticks[rw], duration);
1754+
part_round_stats(cpu, part);
1755+
part_dec_in_flight(part);
17721756

1773-
disk_stat_unlock();
1757+
part_stat_unlock();
17741758
}
17751759

17761760
if (req->end_io)

block/blk-merge.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -390,17 +390,13 @@ static int attempt_merge(struct request_queue *q, struct request *req,
390390
struct hd_struct *part;
391391
int cpu;
392392

393-
cpu = disk_stat_lock();
393+
cpu = part_stat_lock();
394394
part = disk_map_sector_rcu(req->rq_disk, req->sector);
395395

396-
disk_round_stats(cpu, req->rq_disk);
397-
req->rq_disk->in_flight--;
398-
if (part) {
399-
part_round_stats(cpu, part);
400-
part->in_flight--;
401-
}
396+
part_round_stats(cpu, part);
397+
part_dec_in_flight(part);
402398

403-
disk_stat_unlock();
399+
part_stat_unlock();
404400
}
405401

406402
req->ioprio = ioprio_best(req->ioprio, next->ioprio);

block/genhd.c

Lines changed: 24 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ EXPORT_SYMBOL_GPL(disk_part_iter_exit);
176176
* while preemption is disabled.
177177
*
178178
* 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
180180
*/
181181
struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
182182
{
@@ -189,7 +189,7 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
189189
sector < part->start_sect + part->nr_sects)
190190
return part;
191191
}
192-
return NULL;
192+
return &disk->part0;
193193
}
194194
EXPORT_SYMBOL_GPL(disk_map_sector_rcu);
195195

@@ -580,24 +580,24 @@ void __init printk_all_partitions(void)
580580
* numbers in hex - the same format as the root=
581581
* option takes.
582582
*/
583-
printk("%s %10llu %s",
584-
bdevt_str(disk_devt(disk), devt_buf),
585-
(unsigned long long)get_capacity(disk) >> 1,
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");
583+
disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
584+
while ((part = disk_part_iter_next(&piter))) {
585+
bool is_part0 = part == &disk->part0;
593586

594-
/* now show the partitions */
595-
disk_part_iter_init(&piter, disk, 0);
596-
while ((part = disk_part_iter_next(&piter)))
597-
printk(" %s %10llu %s\n",
587+
printk("%s%s %10llu %s", is_part0 ? "" : " ",
598588
bdevt_str(part_devt(part), devt_buf),
599589
(unsigned long long)part->nr_sects >> 1,
600590
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+
}
601601
disk_part_iter_exit(&piter);
602602
}
603603
class_dev_iter_exit(&iter);
@@ -674,12 +674,7 @@ static int show_partition(struct seq_file *seqf, void *v)
674674
return 0;
675675

676676
/* show the full disk and all non-0 size partitions of it */
677-
seq_printf(seqf, "%4d %7d %10llu %s\n",
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);
677+
disk_part_iter_init(&piter, sgp, DISK_PITER_INCL_PART0);
683678
while ((part = disk_part_iter_next(&piter)))
684679
seq_printf(seqf, "%4d %7d %10llu %s\n",
685680
MAJOR(part_devt(part)), MINOR(part_devt(part)),
@@ -768,40 +763,13 @@ static ssize_t disk_capability_show(struct device *dev,
768763
return sprintf(buf, "%x\n", disk->flags);
769764
}
770765

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-
798766
static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
799767
static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
800768
static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
801769
static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL);
802770
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
803771
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);
805773
#ifdef CONFIG_FAIL_MAKE_REQUEST
806774
static struct device_attribute dev_attr_fail =
807775
__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)
836804

837805
kfree(disk->random);
838806
kfree(disk->__part);
839-
free_disk_stats(disk);
807+
free_part_stats(&disk->part0);
840808
kfree(disk);
841809
}
842810
struct class block_class = {
@@ -873,28 +841,11 @@ static int diskstats_show(struct seq_file *seqf, void *v)
873841
"\n\n");
874842
*/
875843

876-
cpu = disk_stat_lock();
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);
844+
disk_part_iter_init(&piter, gp, DISK_PITER_INCL_PART0);
894845
while ((hd = disk_part_iter_next(&piter))) {
895-
cpu = disk_stat_lock();
846+
cpu = part_stat_lock();
896847
part_round_stats(cpu, hd);
897-
disk_stat_unlock();
848+
part_stat_unlock();
898849
seq_printf(seqf, "%4d %7d %s %lu %lu %llu "
899850
"%u %lu %lu %llu %u %u %u %u\n",
900851
MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
@@ -1000,15 +951,15 @@ struct gendisk *alloc_disk_ext_node(int minors, int ext_minors, int node_id)
1000951
int tot_minors = minors + ext_minors;
1001952
int size = tot_minors * sizeof(struct hd_struct *);
1002953

1003-
if (!init_disk_stats(disk)) {
954+
if (!init_part_stats(&disk->part0)) {
1004955
kfree(disk);
1005956
return NULL;
1006957
}
1007958

1008959
disk->__part = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO,
1009960
node_id);
1010961
if (!disk->__part) {
1011-
free_disk_stats(disk);
962+
free_part_stats(&disk->part0);
1012963
kfree(disk);
1013964
return NULL;
1014965
}

drivers/block/aoe/aoecmd.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -758,15 +758,15 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
758758
struct hd_struct *part;
759759
int cpu;
760760

761-
cpu = disk_stat_lock();
761+
cpu = part_stat_lock();
762762
part = disk_map_sector_rcu(disk, sector);
763763

764-
all_stat_inc(cpu, disk, part, ios[rw], sector);
765-
all_stat_add(cpu, disk, part, ticks[rw], duration, sector);
766-
all_stat_add(cpu, disk, part, sectors[rw], n_sect, sector);
767-
all_stat_add(cpu, disk, part, io_ticks, duration, sector);
764+
part_stat_inc(cpu, part, ios[rw]);
765+
part_stat_add(cpu, part, ticks[rw], duration);
766+
part_stat_add(cpu, part, sectors[rw], n_sect);
767+
part_stat_add(cpu, part, io_ticks, duration);
768768

769-
disk_stat_unlock();
769+
part_stat_unlock();
770770
}
771771

772772
void

drivers/md/dm.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,10 @@ static void start_io_acct(struct dm_io *io)
381381

382382
io->start_time = jiffies;
383383

384-
cpu = disk_stat_lock();
385-
disk_round_stats(cpu, dm_disk(md));
386-
disk_stat_unlock();
387-
dm_disk(md)->in_flight = atomic_inc_return(&md->pending);
384+
cpu = part_stat_lock();
385+
part_round_stats(cpu, &dm_disk(md)->part0);
386+
part_stat_unlock();
387+
dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending);
388388
}
389389

390390
static int end_io_acct(struct dm_io *io)
@@ -395,12 +395,13 @@ static int end_io_acct(struct dm_io *io)
395395
int pending, cpu;
396396
int rw = bio_data_dir(bio);
397397

398-
cpu = disk_stat_lock();
399-
disk_round_stats(cpu, dm_disk(md));
400-
disk_stat_add(cpu, dm_disk(md), ticks[rw], duration);
401-
disk_stat_unlock();
398+
cpu = part_stat_lock();
399+
part_round_stats(cpu, &dm_disk(md)->part0);
400+
part_stat_add(cpu, &dm_disk(md)->part0, ticks[rw], duration);
401+
part_stat_unlock();
402402

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);
404405

405406
return !pending;
406407
}
@@ -899,10 +900,10 @@ static int dm_request(struct request_queue *q, struct bio *bio)
899900

900901
down_read(&md->io_lock);
901902

902-
cpu = disk_stat_lock();
903-
disk_stat_inc(cpu, dm_disk(md), ios[rw]);
904-
disk_stat_add(cpu, dm_disk(md), sectors[rw], bio_sectors(bio));
905-
disk_stat_unlock();
903+
cpu = part_stat_lock();
904+
part_stat_inc(cpu, &dm_disk(md)->part0, ios[rw]);
905+
part_stat_add(cpu, &dm_disk(md)->part0, sectors[rw], bio_sectors(bio));
906+
part_stat_unlock();
906907

907908
/*
908909
* If we're suspended we have to queue

0 commit comments

Comments
 (0)