Commit 3eaf840e0b0046f56602c524c7ba58a82f5526c5
Committed by
Linus Torvalds
1 parent
12f03a49cf
Exists in
master
and in
4 other branches
[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>
Showing 2 changed files with 35 additions and 2 deletions Side-by-side Diff
block/ll_rw_blk.c
drivers/md/dm.c
| ... | ... | @@ -31,6 +31,7 @@ |
| 31 | 31 | int error; |
| 32 | 32 | struct bio *bio; |
| 33 | 33 | atomic_t io_count; |
| 34 | + unsigned long start_time; | |
| 34 | 35 | }; |
| 35 | 36 | |
| 36 | 37 | /* |
| ... | ... | @@ -244,6 +245,36 @@ |
| 244 | 245 | mempool_free(tio, md->tio_pool); |
| 245 | 246 | } |
| 246 | 247 | |
| 248 | +static 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 | + | |
| 260 | +static 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 | 279 | * Add the bio to the list of deferred io. |
| 249 | 280 | */ |
| ... | ... | @@ -299,7 +330,7 @@ |
| 299 | 330 | io->error = error; |
| 300 | 331 | |
| 301 | 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 | 334 | /* nudge anyone waiting on suspend queue */ |
| 304 | 335 | wake_up(&io->md->wait); |
| 305 | 336 | |
| ... | ... | @@ -554,7 +585,7 @@ |
| 554 | 585 | ci.sector_count = bio_sectors(bio); |
| 555 | 586 | ci.idx = bio->bi_idx; |
| 556 | 587 | |
| 557 | - atomic_inc(&md->pending); | |
| 588 | + start_io_acct(ci.io); | |
| 558 | 589 | while (ci.sector_count) |
| 559 | 590 | __clone_and_map(&ci); |
| 560 | 591 |