diff options
author | Alan D. Brunelle <Alan.Brunelle@hp.com> | 2007-02-26 20:44:23 +0100 |
---|---|---|
committer | Jens Axboe <axboe@carl.home.kernel.dk> | 2007-02-26 20:44:23 +0100 |
commit | a6c42403c52df673378c30586f673b5fa86b4122 (patch) | |
tree | e77342abd3ef4a0c1b950c9d1049f5f296de06e4 /btt/trace_complete.c | |
parent | db8570e94bedcb7196af5c209ae970afe2918643 (diff) | |
download | blktrace-a6c42403c52df673378c30586f673b5fa86b4122.tar.gz blktrace-a6c42403c52df673378c30586f673b5fa86b4122.tar.bz2 |
Fix remap handling (again).
I guess majors 253 and 254 are both right.
Fixed typo in bilink_first_up.
I'm seeing stuff like:
253,0 0 13 30.716486276 31815 Q R 0 + 8 [mount]
253,0 0 14 30.718087082 3 C R 0 + 8 [0]
Without any intervening stuff (remaps and gets and inserts and ...). So
added some support for this case.
(Note: This requires the kernel patch I submitted on 2007/02/15 to make
any sense, although this code will "work" in any event.)
Signed-off-by: Alan D. Brunelle <Alan.Brunelle@hp.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'btt/trace_complete.c')
-rw-r--r-- | btt/trace_complete.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/btt/trace_complete.c b/btt/trace_complete.c index 5ef23c1..c82ccb3 100644 --- a/btt/trace_complete.c +++ b/btt/trace_complete.c @@ -26,8 +26,17 @@ static inline void __run_complete(struct io *c_iop) { LIST_HEAD(rmhd); - if (remapper_dev(c_iop->t.device)) - bilink_for_each_down(run_remap, c_iop, &rmhd, 1); + if (remapper_dev(c_iop->t.device)) { + struct bilink *blp; + struct io *iop = bilink_first_down(c_iop, &blp); + + if (iop->type == IOP_Q) { + run_queue(iop, c_iop, &rmhd); + biunlink(blp); + } + else + bilink_for_each_down(run_remap, c_iop, &rmhd, 1); + } else bilink_for_each_down(run_issue, c_iop, &rmhd, 1); @@ -44,19 +53,40 @@ static int ready_complete_remapper(struct io *c_iop) { LIST_HEAD(head); struct list_head *p, *q; - struct io *l_iop, *a_iop; dip_foreach_list(c_iop, IOP_L, &head); - list_for_each_safe(p, q, &head) { - l_iop = list_entry(p, struct io, f_head); - LIST_DEL(&l_iop->f_head); - - ASSERT(!list_empty(&l_iop->up_list)); - a_iop = bilink_first_up(l_iop, NULL); - if (ready_remap(a_iop, c_iop)) { - dip_rem(l_iop); - bilink(a_iop, c_iop); - c_iop->bytes_left -= a_iop->t.bytes; + if (list_empty(&head)) { + struct io *q_iop; + + dip_foreach_list(c_iop, IOP_Q, &head); + list_for_each_safe(p, q, &head) { + q_iop = list_entry(p, struct io, f_head); + LIST_DEL(&q_iop->f_head); + + ASSERT(list_empty(&q_iop->up_list)); + ASSERT(list_empty(&q_iop->down_list)); + ASSERT(q_iop->t.bytes == c_iop->t.bytes); + if (ready_queue(q_iop, c_iop)) { + dip_rem(q_iop); + bilink(q_iop, c_iop); + c_iop->bytes_left -= q_iop->t.bytes; + } + } + } + else { + struct io *l_iop, *a_iop; + + list_for_each_safe(p, q, &head) { + l_iop = list_entry(p, struct io, f_head); + LIST_DEL(&l_iop->f_head); + + ASSERT(!list_empty(&l_iop->up_list)); + a_iop = bilink_first_up(l_iop, NULL); + if (ready_remap(a_iop, c_iop)) { + dip_rem(l_iop); + bilink(a_iop, c_iop); + c_iop->bytes_left -= a_iop->t.bytes; + } } } |