aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-08-25 06:47:21 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 02:56:06 -0400
commitc9959059161ddd7bf4670cf47367033d6b2f79c4 (patch)
tree6454db55f8e34361fe472358e10e0c5cfac1e366 /drivers/md
parente71bf0d0ee89e51b92776391c5634938236977d5 (diff)
block: fix diskstats access
There are two variants of stat functions - ones prefixed with double underbars which don't care about preemption and ones without which disable preemption before manipulating per-cpu counters. It's unclear whether the underbarred ones assume that preemtion is disabled on entry as some callers don't do that. This patch unifies diskstats access by implementing disk_stat_lock() and disk_stat_unlock() which take care of both RCU (for partition access) and preemption (for per-cpu counter access). diskstats access should always be enclosed between the two functions. As such, there's no need for the versions which disables preemption. They're removed and double underbars ones are renamed to drop the underbars. As an extra argument is added, there's no danger of using the old version unconverted. disk_stat_lock() uses get_cpu() and returns the cpu index and all diskstat functions which access per-cpu counters now has @cpu argument to help RT. This change adds RCU or preemption operations at some places but also collapses several preemption ops into one at others. Overall, the performance difference should be negligible as all involved ops are very lightweight per-cpu ones. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm.c26
-rw-r--r--drivers/md/linear.c7
-rw-r--r--drivers/md/multipath.c7
-rw-r--r--drivers/md/raid0.c7
-rw-r--r--drivers/md/raid1.c8
-rw-r--r--drivers/md/raid10.c7
-rw-r--r--drivers/md/raid5.c8
7 files changed, 45 insertions, 25 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index a78caad29996..653624792eaf 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -377,12 +377,13 @@ static void free_tio(struct mapped_device *md, struct dm_target_io *tio)
377static void start_io_acct(struct dm_io *io) 377static void start_io_acct(struct dm_io *io)
378{ 378{
379 struct mapped_device *md = io->md; 379 struct mapped_device *md = io->md;
380 int cpu;
380 381
381 io->start_time = jiffies; 382 io->start_time = jiffies;
382 383
383 preempt_disable(); 384 cpu = disk_stat_lock();
384 disk_round_stats(dm_disk(md)); 385 disk_round_stats(cpu, dm_disk(md));
385 preempt_enable(); 386 disk_stat_unlock();
386 dm_disk(md)->in_flight = atomic_inc_return(&md->pending); 387 dm_disk(md)->in_flight = atomic_inc_return(&md->pending);
387} 388}
388 389
@@ -391,15 +392,15 @@ static int end_io_acct(struct dm_io *io)
391 struct mapped_device *md = io->md; 392 struct mapped_device *md = io->md;
392 struct bio *bio = io->bio; 393 struct bio *bio = io->bio;
393 unsigned long duration = jiffies - io->start_time; 394 unsigned long duration = jiffies - io->start_time;
394 int pending; 395 int pending, cpu;
395 int rw = bio_data_dir(bio); 396 int rw = bio_data_dir(bio);
396 397
397 preempt_disable(); 398 cpu = disk_stat_lock();
398 disk_round_stats(dm_disk(md)); 399 disk_round_stats(cpu, dm_disk(md));
399 preempt_enable(); 400 disk_stat_add(cpu, dm_disk(md), ticks[rw], duration);
400 dm_disk(md)->in_flight = pending = atomic_dec_return(&md->pending); 401 disk_stat_unlock();
401 402
402 disk_stat_add(dm_disk(md), ticks[rw], duration); 403 dm_disk(md)->in_flight = pending = atomic_dec_return(&md->pending);
403 404
404 return !pending; 405 return !pending;
405} 406}
@@ -885,6 +886,7 @@ static int dm_request(struct request_queue *q, struct bio *bio)
885 int r = -EIO; 886 int r = -EIO;
886 int rw = bio_data_dir(bio); 887 int rw = bio_data_dir(bio);
887 struct mapped_device *md = q->queuedata; 888 struct mapped_device *md = q->queuedata;
889 int cpu;
888 890
889 /* 891 /*
890 * There is no use in forwarding any barrier request since we can't 892 * There is no use in forwarding any barrier request since we can't
@@ -897,8 +899,10 @@ static int dm_request(struct request_queue *q, struct bio *bio)
897 899
898 down_read(&md->io_lock); 900 down_read(&md->io_lock);
899 901
900 disk_stat_inc(dm_disk(md), ios[rw]); 902 cpu = disk_stat_lock();
901 disk_stat_add(dm_disk(md), sectors[rw], bio_sectors(bio)); 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();
902 906
903 /* 907 /*
904 * If we're suspended we have to queue 908 * If we're suspended we have to queue
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b1eebf88c209..00cbc8e47294 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -318,14 +318,17 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
318 mddev_t *mddev = q->queuedata; 318 mddev_t *mddev = q->queuedata;
319 dev_info_t *tmp_dev; 319 dev_info_t *tmp_dev;
320 sector_t block; 320 sector_t block;
321 int cpu;
321 322
322 if (unlikely(bio_barrier(bio))) { 323 if (unlikely(bio_barrier(bio))) {
323 bio_endio(bio, -EOPNOTSUPP); 324 bio_endio(bio, -EOPNOTSUPP);
324 return 0; 325 return 0;
325 } 326 }
326 327
327 disk_stat_inc(mddev->gendisk, ios[rw]); 328 cpu = disk_stat_lock();
328 disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); 329 disk_stat_inc(cpu, mddev->gendisk, ios[rw]);
330 disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio));
331 disk_stat_unlock();
329 332
330 tmp_dev = which_dev(mddev, bio->bi_sector); 333 tmp_dev = which_dev(mddev, bio->bi_sector);
331 block = bio->bi_sector >> 1; 334 block = bio->bi_sector >> 1;
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index c4779ccba1c3..182f5a94cdc5 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -147,6 +147,7 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio)
147 struct multipath_bh * mp_bh; 147 struct multipath_bh * mp_bh;
148 struct multipath_info *multipath; 148 struct multipath_info *multipath;
149 const int rw = bio_data_dir(bio); 149 const int rw = bio_data_dir(bio);
150 int cpu;
150 151
151 if (unlikely(bio_barrier(bio))) { 152 if (unlikely(bio_barrier(bio))) {
152 bio_endio(bio, -EOPNOTSUPP); 153 bio_endio(bio, -EOPNOTSUPP);
@@ -158,8 +159,10 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio)
158 mp_bh->master_bio = bio; 159 mp_bh->master_bio = bio;
159 mp_bh->mddev = mddev; 160 mp_bh->mddev = mddev;
160 161
161 disk_stat_inc(mddev->gendisk, ios[rw]); 162 cpu = disk_stat_lock();
162 disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); 163 disk_stat_inc(cpu, mddev->gendisk, ios[rw]);
164 disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio));
165 disk_stat_unlock();
163 166
164 mp_bh->path = multipath_map(conf); 167 mp_bh->path = multipath_map(conf);
165 if (mp_bh->path < 0) { 168 if (mp_bh->path < 0) {
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 183610635661..e26030fa59ab 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -399,14 +399,17 @@ static int raid0_make_request (struct request_queue *q, struct bio *bio)
399 sector_t chunk; 399 sector_t chunk;
400 sector_t block, rsect; 400 sector_t block, rsect;
401 const int rw = bio_data_dir(bio); 401 const int rw = bio_data_dir(bio);
402 int cpu;
402 403
403 if (unlikely(bio_barrier(bio))) { 404 if (unlikely(bio_barrier(bio))) {
404 bio_endio(bio, -EOPNOTSUPP); 405 bio_endio(bio, -EOPNOTSUPP);
405 return 0; 406 return 0;
406 } 407 }
407 408
408 disk_stat_inc(mddev->gendisk, ios[rw]); 409 cpu = disk_stat_lock();
409 disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); 410 disk_stat_inc(cpu, mddev->gendisk, ios[rw]);
411 disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio));
412 disk_stat_unlock();
410 413
411 chunk_size = mddev->chunk_size >> 10; 414 chunk_size = mddev->chunk_size >> 10;
412 chunk_sects = mddev->chunk_size >> 9; 415 chunk_sects = mddev->chunk_size >> 9;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 0b82030c265d..babb13036f93 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -779,7 +779,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
779 struct page **behind_pages = NULL; 779 struct page **behind_pages = NULL;
780 const int rw = bio_data_dir(bio); 780 const int rw = bio_data_dir(bio);
781 const int do_sync = bio_sync(bio); 781 const int do_sync = bio_sync(bio);
782 int do_barriers; 782 int cpu, do_barriers;
783 mdk_rdev_t *blocked_rdev; 783 mdk_rdev_t *blocked_rdev;
784 784
785 /* 785 /*
@@ -804,8 +804,10 @@ static int make_request(struct request_queue *q, struct bio * bio)
804 804
805 bitmap = mddev->bitmap; 805 bitmap = mddev->bitmap;
806 806
807 disk_stat_inc(mddev->gendisk, ios[rw]); 807 cpu = disk_stat_lock();
808 disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); 808 disk_stat_inc(cpu, mddev->gendisk, ios[rw]);
809 disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio));
810 disk_stat_unlock();
809 811
810 /* 812 /*
811 * make_request() can abort the operation when READA is being 813 * make_request() can abort the operation when READA is being
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d3b9aa096285..5ec80da0a9d7 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -789,6 +789,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
789 mirror_info_t *mirror; 789 mirror_info_t *mirror;
790 r10bio_t *r10_bio; 790 r10bio_t *r10_bio;
791 struct bio *read_bio; 791 struct bio *read_bio;
792 int cpu;
792 int i; 793 int i;
793 int chunk_sects = conf->chunk_mask + 1; 794 int chunk_sects = conf->chunk_mask + 1;
794 const int rw = bio_data_dir(bio); 795 const int rw = bio_data_dir(bio);
@@ -843,8 +844,10 @@ static int make_request(struct request_queue *q, struct bio * bio)
843 */ 844 */
844 wait_barrier(conf); 845 wait_barrier(conf);
845 846
846 disk_stat_inc(mddev->gendisk, ios[rw]); 847 cpu = disk_stat_lock();
847 disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); 848 disk_stat_inc(cpu, mddev->gendisk, ios[rw]);
849 disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bio));
850 disk_stat_unlock();
848 851
849 r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO); 852 r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO);
850 853
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 37e546528f9c..5899f211515f 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3387,7 +3387,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
3387 sector_t logical_sector, last_sector; 3387 sector_t logical_sector, last_sector;
3388 struct stripe_head *sh; 3388 struct stripe_head *sh;
3389 const int rw = bio_data_dir(bi); 3389 const int rw = bio_data_dir(bi);
3390 int remaining; 3390 int cpu, remaining;
3391 3391
3392 if (unlikely(bio_barrier(bi))) { 3392 if (unlikely(bio_barrier(bi))) {
3393 bio_endio(bi, -EOPNOTSUPP); 3393 bio_endio(bi, -EOPNOTSUPP);
@@ -3396,8 +3396,10 @@ 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 disk_stat_inc(mddev->gendisk, ios[rw]); 3399 cpu = disk_stat_lock();
3400 disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bi)); 3400 disk_stat_inc(cpu, mddev->gendisk, ios[rw]);
3401 disk_stat_add(cpu, mddev->gendisk, sectors[rw], bio_sectors(bi));
3402 disk_stat_unlock();
3401 3403
3402 if (rw == READ && 3404 if (rw == READ &&
3403 mddev->reshape_position == MaxSector && 3405 mddev->reshape_position == MaxSector &&