[PATCH] btt: Cleaned up patches for SEEK additions, DM, Q2A and seek fixes
authorAlan D. Brunelle <Alan.Brunelle@hp.com>
Thu, 14 Sep 2006 23:57:24 +0000 (01:57 +0200)
committerJens Axboe <axboe@kernel.dk>
Thu, 14 Sep 2006 23:57:24 +0000 (01:57 +0200)
Added changes to handle DM devices:

- Used __pad field in struct blk_io_trace_remap to store from device,
  contains partition device information. Required modification in
  blkparse_fmt.c:process_default() to handle this change.

- To better handle DM devices, noted that REMAP traces can refer to other
  REMAP traces, and thus added A_A and A_Q types (much like Q_A and Q_X)
  types.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
blkparse_fmt.c
blktrace_api.h
btt/globals.h
btt/inlines.h
btt/iofree.c
btt/trace.c
btt/traverse.c

index b97f46a8ca0a60b96d4188351951d8d423adba8a..f74832d8c7832f2409dd062f6d979f272e68febd 100644 (file)
@@ -135,6 +135,7 @@ static void get_pdu_remap(struct blk_io_trace *t, struct blk_io_trace_remap *r)
        __u64 sector = __r->sector;
 
        r->device = be32_to_cpu(__r->device);
+       r->device_from = be32_to_cpu(__r->device_from);
        r->sector = be64_to_cpu(sector);
 }
 
@@ -261,6 +262,7 @@ static void process_default(char *act, struct per_cpu_info *pci,
                            struct blk_io_trace *t, unsigned long long elapsed,
                            int pdu_len, unsigned char *pdu_buf)
 {
+       struct blk_io_trace_remap r = { .device = 0, };
        char rwbs[6];
        char *name;
 
@@ -269,6 +271,11 @@ static void process_default(char *act, struct per_cpu_info *pci,
        /*
         * The header is always the same
         */
+       if (act[0] == 'A') {    /* Remap */
+               get_pdu_remap(t, &r);
+               t->device = r.device_from;
+       }
+
        fprintf(ofp, "%3d,%-3d %2d %8d %5d.%09lu %5u %2s %3s ",
                MAJOR(t->device), MINOR(t->device), pci->cpu, t->sequence,
                (int) SECONDS(t->time), (unsigned long) NANO_SECONDS(t->time),
@@ -339,16 +346,12 @@ static void process_default(char *act, struct per_cpu_info *pci,
                fprintf(ofp, "[%s] %u\n", name, get_pdu_int(t));
                break;
 
-       case 'A': {     /* remap */
-               struct blk_io_trace_remap r;
-
-               get_pdu_remap(t, &r);
+       case 'A':       /* remap */
                fprintf(ofp, "%llu + %u <- (%d,%d) %llu\n",
                        (unsigned long long) t->sector, t_sec(t),
                        MAJOR(r.device), MINOR(r.device),
                        (unsigned long long) r.sector);
                break;
-       }
                
        case 'X':       /* Split */
                fprintf(ofp, "%llu / %u [%s]\n", (unsigned long long) t->sector,
index 9a4f7c94ca68f69ea851a97faed51e0d2ea139b3..7585eacef26cbb2e742e8a6600b32b1c862856df 100644 (file)
@@ -92,7 +92,7 @@ struct blk_io_trace {
  */
 struct blk_io_trace_remap {
        __u32 device;
-       __u32 __pad;
+       __u32 device_from;
        __u64 sector;
 };
 
index 463b135e9908b98ab7c1fe0fda6398a13abc3642..7bc89ef918da7ffc7c998f131c030e48f303518e 100644 (file)
@@ -170,8 +170,18 @@ struct io {
                                Q_X = 30,
                        } qp_type;
                }                                         q;
+               struct {
+                       union {
+                               struct io *a_q;
+                               struct io *a_a;
+                       } ap;
+                       enum {
+                               A_NONE = 10,
+                               A_A = 20,
+                               A_Q = 30,
+                       } ap_type;
+               }                                         a;
                struct { struct io *x_q;                } x;
-               struct { struct io *a_q;                } a;
                struct { struct io *m_q;                } m;
                struct { struct list_head i_qs_head;    } i;
                struct { struct list_head d_im_head;    } d;
index 4b7f10e30090309483889a87f8ad402e01d44262..6c7c6406438693c4dd59a15e3c78941af056d913 100644 (file)
@@ -111,6 +111,10 @@ static inline struct list_head *dip_get_head(struct d_info *dip,
 
 static inline struct list_head *dip_get_head_dev(__u32 dev, enum iop_type type)
 {
+       struct d_info *dip = __dip_find(dev);
+
+       if (!dip) 
+               return NULL;
        return dip_get_head(__dip_find(dev), type);
 }
 
index a0af8bb4cb328b6a23db6d5ff83c832da1e8db6a..989186d2dc6ed10860cc4a82fec186828e1e0873 100644 (file)
@@ -26,10 +26,20 @@ void io_free_resources(struct io *iop)
 {
        switch (iop->type) {
        case IOP_X: io_unlink(&iop->u.x.x_q); break;
-       case IOP_A: io_unlink(&iop->u.a.a_q); break;
        case IOP_M: io_unlink(&iop->u.m.m_q); break;
        case IOP_C: io_unlink(&iop->u.c.c_d); break;
 
+       case IOP_A:
+               switch (iop->u.a.ap_type) {
+               case A_NONE: break;
+               case A_Q: io_unlink(&iop->u.a.ap.a_q); break;
+               case A_A: io_unlink(&iop->u.a.ap.a_a); break;
+               default:
+                       ASSERT(0);
+                       /*NOTREACHED*/
+               }
+               break;
+
        case IOP_Q:
                switch (iop->u.q.qp_type) {
                case Q_NONE: break;
index 542512338c29af79d671b8a8417dba8ab272f7f6..076100cd32ff45b80d2b92b4fdcc71002bee0f9f 100644 (file)
@@ -31,7 +31,7 @@ struct io *dip_find_exact(struct list_head *head, struct io *iop_in)
        struct io *iop;
        struct list_head *p;
 
-       __list_for_each(p, head) {
+       if (head != NULL) __list_for_each(p, head) {
                iop = list_entry(p, struct io, dev_head);
                if (is_bit(iop_in, iop))
                        return iop;
@@ -44,7 +44,7 @@ struct io *dip_find_in(struct list_head *head, struct io *iop_in)
        struct io *iop;
        struct list_head *p;
 
-       __list_for_each(p, head) {
+       if (head != NULL) __list_for_each(p, head) {
                iop = list_entry(p, struct io, dev_head);
                if (in_bit(iop, iop_in))
                        return iop;
@@ -57,7 +57,7 @@ struct io *dip_find_start(struct list_head *head, __u64 sector)
        struct io *iop;
        struct list_head *p;
 
-       __list_for_each(p, head) {
+       if (head != NULL) __list_for_each(p, head) {
                iop = list_entry(p, struct io, dev_head);
                if (BIT_START(iop) == sector)
                        return iop;
@@ -70,7 +70,7 @@ struct io *dip_find_end(struct list_head *head, __u64 sector)
        struct io *iop;
        struct list_head *p;
 
-       __list_for_each(p, head) {
+       if (head != NULL) __list_for_each(p, head) {
                iop = list_entry(p, struct io, dev_head);
                if (BIT_END(iop) == sector)
                        return iop;
@@ -83,7 +83,7 @@ struct io *dip_find_in_sec(struct list_head *head, __u64 sector)
        struct io *iop;
        struct list_head *p;
 
-       __list_for_each(p, head) {
+       if (head != NULL) __list_for_each(p, head) {
                iop = list_entry(p, struct io, dev_head);
                if (BIT_START(iop) <= sector && sector <= BIT_END(iop))
                        return iop;
@@ -96,7 +96,7 @@ struct io *dip_find_qa(struct list_head *head, struct blk_io_trace *t)
        struct io *iop;
        struct list_head *p;
 
-       __list_for_each(p, head) {
+       if (head != NULL) __list_for_each(p, head) {
                iop = list_entry(p, struct io, dev_head);
                if (iop->t.cpu == t->cpu && iop->t.sequence == (t->sequence-1))
                        return iop;
@@ -110,7 +110,7 @@ void dip_add_ms(struct list_head *head, struct io *d_iop)
        struct list_head *p;
        struct io_list *iolp;
 
-       __list_for_each(p, head) {
+       if (head != NULL) __list_for_each(p, head) {
                m_iop = list_entry(p, struct io, dev_head);
                if (in_bit(m_iop, d_iop)) {
                        iolp = malloc(sizeof(*iolp));
@@ -126,7 +126,7 @@ void dip_add_qs(struct list_head *head, struct io *i_iop)
        struct list_head *p;
        struct io_list *iolp;
 
-       __list_for_each(p, head) {
+       if (head != NULL) __list_for_each(p, head) {
                q_iop = list_entry(p, struct io, dev_head);
                if (in_bit(q_iop, i_iop)) {
                        iolp = malloc(sizeof(*iolp));
@@ -154,16 +154,6 @@ void handle_queue(struct io *iop)
        }
        else
                iop->u.q.qp_type = Q_NONE;
-
-#if defined(LVM_REMAP_WORKAROUND)
-       if (is_lvm) {
-               tmp = dip_find_qa(dip_get_head(iop->dip, IOP_A), &iop->t);
-               if (tmp) {
-                       iop->u.q.qp_type = Q_A;
-                       io_link(&iop->u.q.qp.q_a, tmp);
-               }
-       }
-#endif
 }
 
 void handle_merge(struct io *iop)
@@ -238,84 +228,29 @@ void handle_split(struct io *iop)
                io_link(&iop->u.x.x_q, q_iop);
 }
 
-#if 0
-void __x_add_c(struct io *y_iop, struct io *x_iop,
-              struct blk_io_trace_split_end *rp, int which)
-{
-       __u32 dev;
-       __u64 sector;
-       struct d_info *dip;
-       struct io **y_cp, *q_iop, *c_iop;
-
-       if (which == 1) {
-               y_cp = &y_iop->u.y.y_c1;
-               dev = be32_to_cpu(rp->dev1);
-               sector = be64_to_cpu(rp->sector1);
-       }
-       else {
-               y_cp = &y_iop->u.y.y_c2;
-               dev = be32_to_cpu(rp->dev2);
-               sector = be64_to_cpu(rp->sector2);
-       }
-
-       dip = __dip_find(dev);
-       ASSERT(dip != NULL);
-
-       q_iop = dip_find_end(dip_get_head(dip, IOP_Q), sector);
-       if (q_iop) {
-               q_iop->u.q.qp_type = Q_X;
-               io_link(&q_iop->u.q.qp.q_x, x_iop);
-       }
-
-       c_iop = dip_find_in_sec(dip_get_head(dip, IOP_C), sector);
-       if (c_iop)
-               io_link(y_cp, c_iop);
-}
-
-void handle_split_end(struct io *iop)
-{
-       struct io *x_iop;
-       struct blk_io_trace_split_end *rp = iop->pdu;
-
-       pending_xs--;
-       io_setup(iop, IOP_Y);
-
-       x_iop = dip_find_exact(dip_get_head(iop->dip, IOP_X), iop);
-       if (x_iop) {
-               __x_add_c(iop, x_iop, rp, 1);
-               __x_add_c(iop, x_iop, rp, 2);
-
-               rem_c(iop->u.y.y_c1);
-               rem_c(iop->u.y.y_c2);
-
-               add_cy(iop);
-       }
-       else
-               release_iop(iop);
-}
-#endif
-
 void handle_remap(struct io *iop)
 {
-       struct io *q_iop;
+       struct io *q_iop, *a_iop;
        struct blk_io_trace_remap *rp = iop->pdu;
        __u32 dev = be32_to_cpu(rp->device);
        __u64 sector = be64_to_cpu(rp->sector);
 
+       io_setup(iop, IOP_A);
        q_iop = dip_find_in_sec(dip_get_head_dev(dev, IOP_Q), sector);
        if (q_iop) {
-               io_setup(iop, IOP_A);
+               iop->u.a.ap_type = A_Q;
+               io_link(&iop->u.a.ap.a_q, q_iop);
+               return;
+       }
 
-#if defined(LVM_REMAP_WORKAROUND)
-               if (is_lvm) {
-                       sector = iop->t.sector;
-                       iop->t.sector = be64_to_cpu(rp->sector);
-               }
-#endif
-               io_link(&iop->u.a.a_q, q_iop);
+       a_iop = dip_find_in_sec(dip_get_head_dev(dev, IOP_A), sector);
+       if (a_iop) {
+               iop->u.a.ap_type = A_A;
+               io_link(&iop->u.a.ap.a_a, a_iop);
+               return;
        }
-       else
-               release_iop(iop);
+
+       iop->u.a.ap_type = A_NONE;
 }
 
 void extract_i(struct io *i_iop)
@@ -390,9 +325,6 @@ void __add_trace(struct io *iop)
        case __BLK_TA_COMPLETE:         handle_complete(iop);   break;
        case __BLK_TA_INSERT:           handle_insert(iop);     break;
        case __BLK_TA_SPLIT:            handle_split(iop);      break;
-#if 0
-       case __BLK_TA_SPLIT_END:        handle_split_end(iop);  break;
-#endif
        case __BLK_TA_REMAP:            handle_remap(iop);      break;
        case __BLK_TA_REQUEUE:          handle_requeue(iop);    break;
        }
index 0c76414140cee630951809c6081245999f657726..0d4b74df7b3f65fbc2df2b1237b6bec013b9f3be 100644 (file)
@@ -98,7 +98,13 @@ struct io *iop_x_func(__u64 *timeline, struct io *iop)
 struct io *iop_a_func(__u64 *timeline, struct io *iop)
 {
        timeline[IOP_A] = iop->t.time;
-       return iop->u.a.a_q;
+       if (iop->u.a.ap_type == A_Q)
+               return 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;
 }
 
 struct io *iop_m_func(__u64 *timeline, struct io *iop)