summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--btt/README8
-rw-r--r--btt/args.c24
-rw-r--r--btt/bt_timeline.c12
-rw-r--r--btt/globals.h6
-rw-r--r--btt/inlines.h10
-rw-r--r--btt/trace.c18
-rw-r--r--btt/trace_complete.c4
-rw-r--r--btt/trace_requeue.c2
8 files changed, 70 insertions, 14 deletions
diff --git a/btt/README b/btt/README
index c4f353d..3ae7779 100644
--- a/btt/README
+++ b/btt/README
@@ -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
--------
diff --git a/btt/args.c b/btt/args.c
index 0e8849c..b0351e8 100644
--- a/btt/args.c
+++ b/btt/args.c
@@ -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);
}