Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2579,6 +2579,8 @@ void disk_round_stats(struct gendisk *disk)
	disk->stamp = now;
}

EXPORT_SYMBOL_GPL(disk_round_stats);

/*
 * queue lock must be held
 */
+33 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct dm_io {
	int error;
	struct bio *bio;
	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)
	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.
 */
@@ -299,7 +330,7 @@ static void dec_pending(struct dm_io *io, int error)
		io->error = error;

	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 */
			wake_up(&io->md->wait);

@@ -554,7 +585,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
	ci.sector_count = bio_sectors(bio);
	ci.idx = bio->bi_idx;

	atomic_inc(&md->pending);
	start_io_acct(ci.io);
	while (ci.sector_count)
		__clone_and_map(&ci);