[PATCH] btt: Fix invalid q2a
authorAlan D. Brunelle <Alan.Brunelle@hp.com>
Fri, 15 Sep 2006 00:00:54 +0000 (02:00 +0200)
committerJens Axboe <axboe@kernel.dk>
Fri, 15 Sep 2006 00:00:54 +0000 (02:00 +0200)
Fix for invalid q2a's under certain circumstances: need to clear out
timeline information as we pop back up stack.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
btt/traverse.c

index 0d4b74df7b3f65fbc2df2b1237b6bec013b9f3be..fd4a847819051544413280fc4a09e88dc49674b9 100644 (file)
  */
 #include "globals.h"
 
-typedef struct io *iop_t;
-typedef iop_t (*iop_func_t)(__u64 *, struct io*);
-
-struct io *iop_q_func(__u64 *timeline, struct io *iop);
-struct io *iop_x_func(__u64 *timeline, struct io *iop);
-struct io *iop_a_func(__u64 *timeline, struct io *iop);
-struct io *iop_m_func(__u64 *timeline, struct io *iop);
-struct io *iop_i_func(__u64 *timeline, struct io *iop);
-struct io *iop_d_func(__u64 *timeline, struct io *iop);
-struct io *iop_c_func(__u64 *timeline, struct io *iop);
-struct io *iop_y_func(__u64 *timeline, struct io *iop);
+int tl_map[] = {
+       IOP_Q,
+       IOP_A,  /* IOP_X */
+       IOP_A,
+       IOP_I,  /* IOP_M */
+       IOP_I,
+       IOP_D,
+       IOP_C,
+       IOP_Y,
+};
+
+
+typedef void (*iop_func_t)(__u64 *, struct io*);
+
+void iop_q_func(__u64 *timeline, struct io *iop);
+void iop_x_func(__u64 *timeline, struct io *iop);
+void iop_a_func(__u64 *timeline, struct io *iop);
+void iop_m_func(__u64 *timeline, struct io *iop);
+void iop_i_func(__u64 *timeline, struct io *iop);
+void iop_d_func(__u64 *timeline, struct io *iop);
+void iop_c_func(__u64 *timeline, struct io *iop);
+void iop_y_func(__u64 *timeline, struct io *iop);
 
 iop_func_t traverse_func[] = {
        iop_q_func,
@@ -45,20 +56,19 @@ iop_func_t traverse_func[] = {
 
 void __traverse(__u64 *timeline, struct io *iop)
 {
-       while (iop != NULL && !iop->traversed) {
+       if (iop != NULL && !iop->traversed) {
                iop->traversed++;
-               iop = traverse_func[iop->type](timeline, iop);
+               timeline[tl_map[iop->type]] = iop->t.time;
+               (traverse_func[iop->type])(timeline, iop);
+               timeline[tl_map[iop->type]] = 0;
        }
 }
 
 void traverse(struct io *iop)
 {
-       int i;
        __u64 timeline[N_IOP_TYPES];
 
-       for (i = 0; i < N_IOP_TYPES; i++)
-               timeline[i] = 0.0;
-
+       memset(timeline, 0, N_IOP_TYPES * sizeof(__u64));
        __traverse(timeline, iop);
 }
 
@@ -75,82 +85,62 @@ void iop_q_update(__u64 *timeline, struct io *iop, __u64 q_time)
        update_d2c(iop, timeline[IOP_C] - timeline[IOP_D]);
 }
 
-struct io *iop_q_func(__u64 *timeline, struct io *iop)
+void iop_q_func(__u64 *timeline, struct io *iop)
 {
-       timeline[IOP_Q] = iop->t.time;
        iop_q_update(timeline, iop, iop->t.time);
-
        if (iop->u.q.qp_type == Q_A)
-               return iop->u.q.qp.q_a;
+               __traverse(timeline, iop->u.q.qp.q_a);
        else if (iop->u.q.qp_type == Q_X)
-               return iop->u.q.qp.q_x;
-
-       /* Q_NONE */
-       return NULL;
+               __traverse(timeline, iop->u.q.qp.q_x);
 }
 
-struct io *iop_x_func(__u64 *timeline, struct io *iop)
+void iop_x_func(__u64 *timeline, struct io *iop)
 {
-       timeline[IOP_A] = iop->t.time;  // Cover X & A in one slice
-       return iop->u.x.x_q;
+       __traverse(timeline, iop->u.x.x_q);
 }
 
-struct io *iop_a_func(__u64 *timeline, struct io *iop)
+void iop_a_func(__u64 *timeline, struct io *iop)
 {
-       timeline[IOP_A] = iop->t.time;
        if (iop->u.a.ap_type == A_Q)
-               return iop->u.a.ap.a_q;
+               __traverse(timeline, iop->u.a.ap.a_q);
        else if (iop->u.a.ap_type == A_A)
-               return iop->u.a.ap.a_a;
-
-       /* A_NONE */
-       return NULL;
+               __traverse(timeline, iop->u.a.ap.a_a);
 }
 
-struct io *iop_m_func(__u64 *timeline, struct io *iop)
+void iop_m_func(__u64 *timeline, struct io *iop)
 {
-       timeline[IOP_I] = iop->t.time;  // Cover M & I in one slice
-       return iop->u.m.m_q;
+       __traverse(timeline, iop->u.m.m_q);
 }
 
-struct io *iop_i_func(__u64 *timeline, struct io *iop)
+void iop_i_func(__u64 *timeline, struct io *iop)
 {
        struct list_head *p;
        struct io_list *iolp;
 
-       timeline[IOP_I] = iop->t.time;
        __list_for_each(p, &iop->u.i.i_qs_head) {
                iolp = list_entry(p, struct io_list, head);
                __traverse(timeline, iolp->iop);
        }
-
-       return NULL;
 }
 
-struct io *iop_d_func(__u64 *timeline, struct io *iop)
+void iop_d_func(__u64 *timeline, struct io *iop)
 {
        struct list_head *p;
        struct io_list *iolp;
 
-       timeline[IOP_D] = iop->t.time;
        __list_for_each(p, &iop->u.d.d_im_head) {
                iolp = list_entry(p, struct io_list, head);
                __traverse(timeline, iolp->iop);
        }
-
-       return NULL;
 }
 
-struct io *iop_c_func(__u64 *timeline, struct io *iop)
+void iop_c_func(__u64 *timeline, struct io *iop)
 {
-       timeline[IOP_C] = iop->t.time;
-       return iop->u.c.c_d;
+       __traverse(timeline, iop->u.c.c_d);
 }
 
-struct io *iop_y_func(__u64 *timeline, struct io *iop)
+void iop_y_func(__u64 *timeline, struct io *iop)
 {
-       timeline[IOP_Y] = iop->t.time;
        __traverse(timeline, iop->u.y.y_c1);
        __traverse(timeline, iop->u.y.y_c2);
-       return NULL;
 }