[PATCH] BTT patch: (3/3) time bounded trace analysis
authorJens Axboe <jens.axboe@oracle.com>
Fri, 1 Dec 2006 09:51:31 +0000 (10:51 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 1 Dec 2006 09:51:31 +0000 (10:51 +0100)
Added in -t and -T options to allow bounding of traces analyzed. Be
forewarned: this can result in some excessive numbers of orphaned traces
(partial IO streams before the -t tiem and after the -T time won't
be analyzed).

Signed-off-by: Alan D. Brunelle <Alan.Brunelle@hp.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
btt/README
btt/args.c
btt/bt_timeline.c
btt/globals.h
btt/inlines.h
btt/trace.c
btt/trace_complete.c
btt/trace_requeue.c

index c4f353dcb409ab75ebafec978feaeea9e07647f4..3ae7779ad43d974aeb772ffecc0e8adbb85f7503 100644 (file)
@@ -20,6 +20,8 @@ Usage: btt
        [ -q <output name> | --q2c-latencies=<output name> ]
        [ -s <output name> | --seeks=<output name> ]
        [ -S <interval>    | --iostat-interval=<interval> ]
+       [ -t <sec>         | --time-start=<sec> ]
+       [ -T <sec>         | --time-end=<sec> ]
        [ -V               | --version ]
        [ -v               | --verbose ]
 
@@ -58,6 +60,12 @@ The -s option instructs btt to output seek data, the argument provided
 is the basis for file names output. There are two files per device,
 read seeks and write seeks.
 
+The -t/-T options allow one to set a start and/or end time for analyzing
+- analyzing will only be done for traces after -t's argument and before
+-T's argument. (-t and -T are optional, so if you specify just -t,
+analysis will occur for all traces after the time specified. Similarly,
+if only -T is specified, analysis stops after -T's seconds.)
+
 Overview
 --------
 
index 0e8849c5a1f20b39e89931bc8077663de4b35ad6..b0351e8b805a79adb472b4b03ffacfb424eb6e13 100644 (file)
@@ -27,7 +27,7 @@
 #include <fcntl.h>
 #include "globals.h"
 
-#define S_OPTS "d:D:e:hi:I:l:M:o:p:q:s:S:Vv"
+#define S_OPTS "d:D:e:hi:I:l:M:o:p:q:s:S:t:T:Vv"
 static struct option l_opts[] = {
        {
                .name = "range-delta",
@@ -107,6 +107,18 @@ static struct option l_opts[] = {
                .flag = NULL,
                .val = 'S'
        },
+       {
+               .name = "time-start",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 't'
+       },
+       {
+               .name = "time-end",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'T'
+       },
        {
                .name = "version",
                .has_arg = no_argument,
@@ -138,6 +150,8 @@ static char usage_str[] = \
        "[ -q <output name> | --q2c-latencies=<output name> ]\n" \
        "[ -s <output name> | --seeks=<output name> ]\n" \
        "[ -S <interval>    | --iostat-interval=<interval> ]\n" \
+       "[ -t <sec>         | --time-start=<sec> ]\n" \
+       "[ -T <sec>         | --time-end=<sec> ]\n" \
        "[ -V               | --version ]\n" \
        "[ -v               | --verbose ]\n\n";
 
@@ -196,6 +210,14 @@ void handle_args(int argc, char *argv[])
                        iostat_interval = (__u64)interval * 1000000000LL;
                        break;
                }
+               case 't':
+                       sscanf(optarg, "%lf", &t_astart);
+                       time_bounded = 1;
+                       break;
+               case 'T':
+                       sscanf(optarg, "%lf", &t_aend);
+                       time_bounded = 1;
+                       break;
                case 'v':
                        verbose = 1;
                        break;
index 1c0855f3d813c4121547ccdae694b17a1c610cb8..fa5678087b69de800007aa5326a5cd4ffc61f37c 100644 (file)
@@ -27,18 +27,20 @@ char bt_timeline_version[] = "0.99";
 
 char *devices, *exes, *input_name, *output_name, *seek_name;
 char *d2c_name, *q2c_name, *per_io_name;
-double range_delta = 0.1;
 FILE *ranges_ofp, *avgs_ofp, *per_io_ofp;
-int ifd, verbose = 0;
+int ifd, verbose, done, time_bounded;
+double t_astart, t_aend;
 unsigned long n_traces;
 struct avgs_info all_avgs;
-__u64 last_q = (__u64)-1;
 unsigned int n_devs;
 time_t genesis, last_vtrace;
 LIST_HEAD(all_devs);
 LIST_HEAD(all_procs);
 LIST_HEAD(free_ios);
 
+double range_delta = 0.1;
+__u64 last_q = (__u64)-1;
+
 struct region_info all_regions = {
        .qranges = LIST_HEAD_INIT(all_regions.qranges),
        .cranges = LIST_HEAD_INIT(all_regions.cranges),
@@ -67,7 +69,7 @@ int process(void)
        struct io *iop = io_alloc();
 
        genesis = last_vtrace = time(NULL);
-       while (!do_read(ifd, &iop->t, sizeof(struct blk_io_trace))) {
+       while (!done && !do_read(ifd, &iop->t, sizeof(struct blk_io_trace))) {
                t = convert_to_cpu(&iop->t);
                if (t->pdu_len > 0) {
                        iop->pdu = malloc(t->pdu_len);
@@ -79,7 +81,9 @@ int process(void)
                add_trace(iop);
                iop = io_alloc();
        }
+
        io_release(iop);
+       do_retries();
 
        if (iostat_ofp) {
                fprintf(iostat_ofp, "\n");
index b94b25f4158572d11ef2f2a41f942221854bc80a..802ff95f26b641f484d0cbb8242892434bb74236 100644 (file)
@@ -169,7 +169,7 @@ struct io {
        struct list_head down_head, up_head, c_pending, retry;
        struct list_head down_list, up_list;
        __u64 bytes_left;
-       int run_ready, linked, self_remap, displayed;
+       int run_ready, linked, self_remap, displayed, on_retry_list;
 };
 
 /* bt_timeline.c */
@@ -178,7 +178,7 @@ extern char bt_timeline_version[], *devices, *exes, *input_name, *output_name;
 extern char *seek_name, *iostat_name, *d2c_name, *q2c_name, *per_io_name;
 extern double range_delta;
 extern FILE *ranges_ofp, *avgs_ofp, *iostat_ofp, *per_io_ofp;;
-extern int verbose, ifd, dump_level;
+extern int verbose, ifd, dump_level, done, time_bounded;
 extern unsigned int n_devs;
 extern unsigned long n_traces;
 extern struct list_head all_devs, all_procs, retries;
@@ -188,6 +188,7 @@ extern struct region_info all_regions;
 extern struct list_head free_ios;
 extern __u64 iostat_interval, iostat_last_stamp;
 extern time_t genesis, last_vtrace;
+extern double t_astart, t_aend;
 
 /* args.c */
 void handle_args(int argc, char *argv[]);
@@ -262,6 +263,7 @@ int seeki_mode(void *handle, struct mode *mp);
 void dump_iop(FILE *ofp, struct io *to_iop, struct io *from_iop, int indent);
 void release_iops(struct list_head *del_head);
 void add_trace(struct io *iop);
+void do_retries(void);
 
 /* trace_complete.c */
 void trace_complete(struct io *c_iop);
index 4a763b5872e5e928c5aead50d3a2cc24e919e5b6..cfc7160b37666cd5ab37291bca533a6a2e6418ef 100644 (file)
@@ -259,12 +259,18 @@ static inline void __unlink(struct io *down_iop, struct io *up_iop)
 
 static inline void add_retry(struct io *iop)
 {
-       list_add_tail(&iop->retry, &retries);
+       if (!iop->on_retry_list) {
+               list_add_tail(&iop->retry, &retries);
+               iop->on_retry_list = 1;
+       }
 }
 
 static inline void del_retry(struct io *iop)
 {
-       LIST_DEL(&iop->retry);
+       if (iop->on_retry_list) {
+               LIST_DEL(&iop->retry);
+               iop->on_retry_list = 0;
+       }
 }
 
 static inline __u64 tdelta(struct io *iop1, struct io *iop2)
index 4c57b5df202b02e91e530cf8b64f6adc1dd19962..50de1bc2d1076fc9069b70f456c8d26a0361a80f 100644 (file)
@@ -85,7 +85,7 @@ void release_iops(struct list_head *del_head)
        }
 }
 
-static void do_retries(void)
+void do_retries(void)
 {
        struct io *iop;
        struct list_head *p, *q;
@@ -135,7 +135,7 @@ static void __add_trace(struct io *iop)
 
 void add_trace(struct io *iop)
 {
-       if (iop->t.time == 15717167961) dbg_ping();
+
        if (iop->t.action & BLK_TC_ACT(BLK_TC_NOTIFY)) {
                char *slash = strchr(iop->pdu, '/');
 
@@ -147,6 +147,18 @@ void add_trace(struct io *iop)
        }
        else if (iop->t.action & BLK_TC_ACT(BLK_TC_PC))
                io_release(iop);
-       else
+       else {
+               if (time_bounded) {
+                       if (BIT_TIME(iop->t.time) < t_astart) {
+                               io_release(iop);
+                               return;
+                       }
+                       else if (BIT_TIME(iop->t.time) > t_aend) {
+                               io_release(iop);
+                               done = 1;
+                               return;
+                       }
+               }
                __add_trace(iop);
+       }
 }
index d8e7b5a9541442e136272386f194c7bdb6dcaf22..32c43b5e7d7424fa5872e41f0746ab3906d6ec3f 100644 (file)
@@ -74,8 +74,11 @@ static void run_comp(struct io *c_iop, struct io *top, struct list_head *rmhd)
                        dump_level--;
                }
        }
+
        dump_iop(per_io_ofp, c_iop, NULL, 0);
+
        LIST_DEL(&c_iop->c_pending);
+       del_retry(c_iop);
        list_add_tail(&c_iop->f_head, rmhd);
 }
 
@@ -122,7 +125,6 @@ int retry_complete(struct io *c_iop)
        if (!ready_complete(c_iop, c_iop))
                return 0;
 
-       del_retry(c_iop);
        run_complete(c_iop);
        return 1;
 }
index 66f3b05077425a4d73283aa84b0fdd96c8d1bc44..55bb3f4e19c54346c578e6a359546389cee0a068 100644 (file)
@@ -38,7 +38,6 @@ int retry_requeue(struct io *r_iop)
        if (!ready_requeue(r_iop, r_iop))
                return 0;
 
-       del_retry(r_iop);
        run_requeue(r_iop);
        return 1;
 }
@@ -60,6 +59,7 @@ void run_requeue(struct io *r_iop)
        run_unissue(d_iop, &del_head);
        __unlink(d_iop, r_iop);
 
+       del_retry(r_iop);
        list_add_tail(&r_iop->f_head, &del_head);
        release_iops(&del_head);
 }