aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
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/dm.c
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/dm.c')
-rw-r--r--drivers/md/dm.c26
1 files changed, 15 insertions, 11 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