From 97d13fb0f2a680668a79e64b7c71f93bd2664b0d Mon Sep 17 00:00:00 2001 From: "Alan D. Brunelle" Date: Fri, 15 Sep 2006 01:57:24 +0200 Subject: [PATCH] [PATCH] btt: Cleaned up patches for SEEK additions, DM, Q2A and seek fixes 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 --- blkparse_fmt.c | 13 +++--- blktrace_api.h | 2 +- btt/globals.h | 12 +++++- btt/inlines.h | 4 ++ btt/iofree.c | 12 +++++- btt/trace.c | 110 ++++++++++--------------------------------------- btt/traverse.c | 8 +++- 7 files changed, 63 insertions(+), 98 deletions(-) diff --git a/blkparse_fmt.c b/blkparse_fmt.c index b97f46a..f74832d 100644 --- a/blkparse_fmt.c +++ b/blkparse_fmt.c @@ -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, diff --git a/blktrace_api.h b/blktrace_api.h index 9a4f7c9..7585eac 100644 --- a/blktrace_api.h +++ b/blktrace_api.h @@ -92,7 +92,7 @@ struct blk_io_trace { */ struct blk_io_trace_remap { __u32 device; - __u32 __pad; + __u32 device_from; __u64 sector; }; diff --git a/btt/globals.h b/btt/globals.h index 463b135..7bc89ef 100644 --- a/btt/globals.h +++ b/btt/globals.h @@ -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; diff --git a/btt/inlines.h b/btt/inlines.h index 4b7f10e..6c7c640 100644 --- a/btt/inlines.h +++ b/btt/inlines.h @@ -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); } diff --git a/btt/iofree.c b/btt/iofree.c index a0af8bb..989186d 100644 --- a/btt/iofree.c +++ b/btt/iofree.c @@ -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; diff --git a/btt/trace.c b/btt/trace.c index 5425123..076100c 100644 --- a/btt/trace.c +++ b/btt/trace.c @@ -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; } diff --git a/btt/traverse.c b/btt/traverse.c index 0c76414..0d4b74d 100644 --- a/btt/traverse.c +++ b/btt/traverse.c @@ -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) -- 2.25.1