diff options
-rw-r--r-- | btt/README | 8 | ||||
-rw-r--r-- | btt/args.c | 24 | ||||
-rw-r--r-- | btt/bt_timeline.c | 12 | ||||
-rw-r--r-- | btt/globals.h | 6 | ||||
-rw-r--r-- | btt/inlines.h | 10 | ||||
-rw-r--r-- | btt/trace.c | 18 | ||||
-rw-r--r-- | btt/trace_complete.c | 4 | ||||
-rw-r--r-- | btt/trace_requeue.c | 2 |
8 files changed, 70 insertions, 14 deletions
@@ -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 -------- @@ -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", @@ -108,6 +108,18 @@ static struct option l_opts[] = { .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, .flag = NULL, @@ -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; diff --git a/btt/bt_timeline.c b/btt/bt_timeline.c index 1c0855f..fa56780 100644 --- a/btt/bt_timeline.c +++ b/btt/bt_timeline.c @@ -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"); diff --git a/btt/globals.h b/btt/globals.h index b94b25f..802ff95 100644 --- a/btt/globals.h +++ b/btt/globals.h @@ -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); diff --git a/btt/inlines.h b/btt/inlines.h index 4a763b5..cfc7160 100644 --- a/btt/inlines.h +++ b/btt/inlines.h @@ -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) diff --git a/btt/trace.c b/btt/trace.c index 4c57b5d..50de1bc 100644 --- a/btt/trace.c +++ b/btt/trace.c @@ -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); + } } diff --git a/btt/trace_complete.c b/btt/trace_complete.c index d8e7b5a..32c43b5 100644 --- a/btt/trace_complete.c +++ b/btt/trace_complete.c @@ -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; } diff --git a/btt/trace_requeue.c b/btt/trace_requeue.c index 66f3b05..55bb3f4 100644 --- a/btt/trace_requeue.c +++ b/btt/trace_requeue.c @@ -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); } |