aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
authorJun'ichi "Nick" Nomura <j-nomura@ce.jp.nec.com>2006-02-01 06:04:53 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-01 11:53:11 -0500
commit3eaf840e0b0046f56602c524c7ba58a82f5526c5 (patch)
treede525d358029dd1744aa2570fe8b8f8add5f8dd1 /drivers/md/dm.c
parent12f03a49cf0ab5e8511911142d28699499a572c4 (diff)
[PATCH] device-mapper disk statistics: timing
Record I/O timing statistics The start time is added to struct dm_io, an existing structure allocated privately internally within dm and attached to each incoming bio. We export disk_round_stats() from block/ll_rw_blk.c instead of creating a private clone. Signed-off-by: Jun'ichi "Nick" Nomura <j-nomura@ce.jp.nec.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index c47518386c91..e9adeb9d172f 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -31,6 +31,7 @@ struct dm_io {
31 int error; 31 int error;
32 struct bio *bio; 32 struct bio *bio;
33 atomic_t io_count; 33 atomic_t io_count;
34 unsigned long start_time;
34}; 35};
35 36
36/* 37/*
@@ -244,6 +245,36 @@ static inline void free_tio(struct mapped_device *md, struct target_io *tio)
244 mempool_free(tio, md->tio_pool); 245 mempool_free(tio, md->tio_pool);
245} 246}
246 247
248static void start_io_acct(struct dm_io *io)
249{
250 struct mapped_device *md = io->md;
251
252 io->start_time = jiffies;
253
254 preempt_disable();
255 disk_round_stats(dm_disk(md));
256 preempt_enable();
257 dm_disk(md)->in_flight = atomic_inc_return(&md->pending);
258}
259
260static int end_io_acct(struct dm_io *io)
261{
262 struct mapped_device *md = io->md;
263 struct bio *bio = io->bio;
264 unsigned long duration = jiffies - io->start_time;
265 int pending;
266 int rw = bio_data_dir(bio);
267
268 preempt_disable();
269 disk_round_stats(dm_disk(md));
270 preempt_enable();
271 dm_disk(md)->in_flight = pending = atomic_dec_return(&md->pending);
272
273 disk_stat_add(dm_disk(md), ticks[rw], duration);
274
275 return !pending;
276}
277
247/* 278/*
248 * Add the bio to the list of deferred io. 279 * Add the bio to the list of deferred io.
249 */ 280 */
@@ -299,7 +330,7 @@ static void dec_pending(struct dm_io *io, int error)
299 io->error = error; 330 io->error = error;
300 331
301 if (atomic_dec_and_test(&io->io_count)) { 332 if (atomic_dec_and_test(&io->io_count)) {
302 if (atomic_dec_and_test(&io->md->pending)) 333 if (end_io_acct(io))
303 /* nudge anyone waiting on suspend queue */ 334 /* nudge anyone waiting on suspend queue */
304 wake_up(&io->md->wait); 335 wake_up(&io->md->wait);
305 336
@@ -554,7 +585,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
554 ci.sector_count = bio_sectors(bio); 585 ci.sector_count = bio_sectors(bio);
555 ci.idx = bio->bi_idx; 586 ci.idx = bio->bi_idx;
556 587
557 atomic_inc(&md->pending); 588 start_io_acct(ci.io);
558 while (ci.sector_count) 589 while (ci.sector_count)
559 __clone_and_map(&ci); 590 __clone_and_map(&ci);
560 591