Commit 3eaf840e authored by Jun'ichi "Nick" Nomura's avatar Jun'ichi "Nick" Nomura Committed by Linus Torvalds

[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: default avatarJun'ichi "Nick" Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 12f03a49
...@@ -2579,6 +2579,8 @@ void disk_round_stats(struct gendisk *disk) ...@@ -2579,6 +2579,8 @@ void disk_round_stats(struct gendisk *disk)
disk->stamp = now; disk->stamp = now;
} }
EXPORT_SYMBOL_GPL(disk_round_stats);
/* /*
* queue lock must be held * queue lock must be held
*/ */
......
...@@ -31,6 +31,7 @@ struct dm_io { ...@@ -31,6 +31,7 @@ struct dm_io {
int error; int error;
struct bio *bio; struct bio *bio;
atomic_t io_count; atomic_t io_count;
unsigned long start_time;
}; };
/* /*
...@@ -244,6 +245,36 @@ static inline void free_tio(struct mapped_device *md, struct target_io *tio) ...@@ -244,6 +245,36 @@ static inline void free_tio(struct mapped_device *md, struct target_io *tio)
mempool_free(tio, md->tio_pool); mempool_free(tio, md->tio_pool);
} }
static void start_io_acct(struct dm_io *io)
{
struct mapped_device *md = io->md;
io->start_time = jiffies;
preempt_disable();
disk_round_stats(dm_disk(md));
preempt_enable();
dm_disk(md)->in_flight = atomic_inc_return(&md->pending);
}
static int end_io_acct(struct dm_io *io)
{
struct mapped_device *md = io->md;
struct bio *bio = io->bio;
unsigned long duration = jiffies - io->start_time;
int pending;
int rw = bio_data_dir(bio);
preempt_disable();
disk_round_stats(dm_disk(md));
preempt_enable();
dm_disk(md)->in_flight = pending = atomic_dec_return(&md->pending);
disk_stat_add(dm_disk(md), ticks[rw], duration);
return !pending;
}
/* /*
* Add the bio to the list of deferred io. * Add the bio to the list of deferred io.
*/ */
...@@ -299,7 +330,7 @@ static void dec_pending(struct dm_io *io, int error) ...@@ -299,7 +330,7 @@ static void dec_pending(struct dm_io *io, int error)
io->error = error; io->error = error;
if (atomic_dec_and_test(&io->io_count)) { if (atomic_dec_and_test(&io->io_count)) {
if (atomic_dec_and_test(&io->md->pending)) if (end_io_acct(io))
/* nudge anyone waiting on suspend queue */ /* nudge anyone waiting on suspend queue */
wake_up(&io->md->wait); wake_up(&io->md->wait);
...@@ -554,7 +585,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio) ...@@ -554,7 +585,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
ci.sector_count = bio_sectors(bio); ci.sector_count = bio_sectors(bio);
ci.idx = bio->bi_idx; ci.idx = bio->bi_idx;
atomic_inc(&md->pending); start_io_acct(ci.io);
while (ci.sector_count) while (ci.sector_count)
__clone_and_map(&ci); __clone_and_map(&ci);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment