Fix remap handling (again).
authorAlan D. Brunelle <Alan.Brunelle@hp.com>
Mon, 26 Feb 2007 19:44:23 +0000 (20:44 +0100)
committerJens Axboe <axboe@carl.home.kernel.dk>
Mon, 26 Feb 2007 19:44:23 +0000 (20:44 +0100)
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>
btt/inlines.h
btt/trace_complete.c

index c93fee49a788fd98506a4038e192c50d4ea56a36..5eb183ca84aa09d5d693719f79a99515fb67b862 100644 (file)
@@ -321,8 +321,7 @@ static inline __u64 tdelta(struct io *iop1, struct io *iop2)
 static inline int remapper_dev(__u32 dev)
 {
        int mjr = MAJOR(dev);
-       return mjr == 9 || mjr == 254;  // 253? That's what is in blkparse.c
-                                       // But I see 254...
+       return mjr == 9 || mjr == 253 || mjr == 254;
 }
 
 static inline void dump_iop(struct io *iop, int extra_nl)
@@ -416,7 +415,7 @@ static inline struct io *bilink_first_up(struct io *iop, struct bilink **blp_p)
 
        if (blp_p != NULL) 
                *blp_p = blp;
-       return blp->diop;
+       return blp->uiop;
 }
 
 typedef void (*bilink_func)(struct io *diop, struct io *uiop, void *param);
index 5ef23c16c90fe2c393d76d317c624f67846f2409..c82ccb3f435795d997fd2553807ab9dd7cf328e8 100644 (file)
@@ -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;
+                       }
                }
        }