summaryrefslogtreecommitdiff
path: root/btt
diff options
context:
space:
mode:
authorAlan D. Brunelle <alan.brunelle@hp.com>2008-11-11 13:46:13 -0500
committerAlan D. Brunelle <alan.brunelle@hp.com>2008-11-11 13:46:13 -0500
commita22df989ded0fb438dcad77a08c59a1a16b6b849 (patch)
tree763690b7e6ba7d84fcc680db2ad73ec3f07e76e5 /btt
parent9638f3909854d936f4a55a48f787364abdbda71f (diff)
downloadblktrace-a22df989ded0fb438dcad77a08c59a1a16b6b849.tar.gz
blktrace-a22df989ded0fb438dcad77a08c59a1a16b6b849.tar.bz2
Added -P to create a data file w/ Q, D and C per line
Easy parsing for graph creation
Diffstat (limited to 'btt')
-rw-r--r--btt/args.c12
-rw-r--r--btt/bt_timeline.c4
-rw-r--r--btt/devs.c15
-rw-r--r--btt/doc/btt.tex9
-rw-r--r--btt/globals.h3
-rw-r--r--btt/trace_complete.c18
6 files changed, 56 insertions, 5 deletions
diff --git a/btt/args.c b/btt/args.c
index 5555e4f..c648b93 100644
--- a/btt/args.c
+++ b/btt/args.c
@@ -29,7 +29,7 @@
#define SETBUFFER_SIZE (64 * 1024)
-#define S_OPTS "aAB:d:D:e:hi:I:l:L:m:M:o:p:q:Q:s:S:t:T:u:VvXz:"
+#define S_OPTS "aAB:d:D:e:hi:I:l:L:m:M:o:p:P:q:Q:s:S:t:T:u:VvXz:"
static struct option l_opts[] = {
{
.name = "seek-absolute",
@@ -122,6 +122,12 @@ static struct option l_opts[] = {
.val = 'p'
},
{
+ .name = "per-io-trees",
+ .has_arg = required_argument,
+ .flag = NULL,
+ .val = 'P'
+ },
+ {
.name = "q2c-latencies",
.has_arg = required_argument,
.flag = NULL,
@@ -208,6 +214,7 @@ static char usage_str[] = \
"[ -M <dev map> | --dev-maps=<dev map>\n" \
"[ -o <output name> | --output-file=<output name> ]\n" \
"[ -p <output name> | --per-io-dump=<output name> ]\n" \
+ "[ -P <output name> | --per-io-trees=<output name> ]\n" \
"[ -q <output name> | --q2c-latencies=<output name> ]\n" \
"[ -Q <output name> | --active-queue-depth=<output name> ]\n" \
"[ -s <output name> | --seeks=<output name> ]\n" \
@@ -308,6 +315,9 @@ void handle_args(int argc, char *argv[])
case 'p':
per_io_name = strdup(optarg);
break;
+ case 'P':
+ per_io_trees = strdup(optarg);
+ break;
case 'q':
q2c_name = strdup(optarg);
break;
diff --git a/btt/bt_timeline.c b/btt/bt_timeline.c
index 734ca35..dda4622 100644
--- a/btt/bt_timeline.c
+++ b/btt/bt_timeline.c
@@ -25,11 +25,11 @@
#include <time.h>
#include "globals.h"
-char bt_timeline_version[] = "2.06";
+char bt_timeline_version[] = "2.07";
char *devices, *exes, *input_name, *output_name, *seek_name, *bno_dump_name;
char *d2c_name, *q2c_name, *per_io_name, *unplug_hist_name;
-char *sps_name, *aqd_name, *q2d_name;
+char *sps_name, *aqd_name, *q2d_name, *per_io_trees;
FILE *ranges_ofp, *avgs_ofp, *xavgs_ofp, *per_io_ofp, *msgs_ofp;
int verbose, done, time_bounded, output_all_data, seek_absolute;
int easy_parse_avgs;
diff --git a/btt/devs.c b/btt/devs.c
index 6c9870f..e530477 100644
--- a/btt/devs.c
+++ b/btt/devs.c
@@ -93,6 +93,8 @@ void dip_exit(void)
unplug_hist_exit(dip->unplug_hist_handle);
if (output_all_data)
q2d_release(dip->q2d_priv);
+ if (dip->pit_fp)
+ fclose(dip->pit_fp);
free(dip);
}
}
@@ -106,6 +108,16 @@ static inline char *mkhandle(char *str, __u32 device, char *post)
return str;
}
+static inline FILE *open_pit(char *str)
+{
+ FILE *fp = fopen(str, "w");
+
+ if (fp == NULL)
+ perror(str);
+
+ return fp;
+}
+
struct d_info *dip_add(__u32 device, struct io *iop)
{
struct d_info *dip = __dip_find(device);
@@ -139,6 +151,9 @@ struct d_info *dip_add(__u32 device, struct io *iop)
if (output_all_data)
dip->q2d_priv = q2d_init();
n_devs++;
+ if (per_io_trees)
+ dip->pit_fp = open_pit(mkhandle(per_io_trees,
+ device, "_pit.dat"));
}
if (dip->pre_culling) {
diff --git a/btt/doc/btt.tex b/btt/doc/btt.tex
index 5f7ef1c..4f59971 100644
--- a/btt/doc/btt.tex
+++ b/btt/doc/btt.tex
@@ -799,7 +799,7 @@ Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s
\newpage\section{\label{sec:cmd-line}Command Line}
\begin{verbatim}
-Usage: btt 2.06
+Usage: btt 2.07
[ -a | --seek-absolute ]
[ -A | --all-data ]
[ -B <output name> | --dump-blocknos=<output name> ]
@@ -815,6 +815,7 @@ Usage: btt 2.06
[ -M <dev map> | --dev-maps=<dev map>
[ -o <output name> | --output-file=<output name> ]
[ -p <output name> | --per-io-dump=<output name> ]
+[ -P <output name> | --per-io-trees=<output name> ]
[ -q <output name> | --q2c-latencies=<output name> ]
[ -Q <output name> | --active-queue-depth=<output name> ]
[ -s <output name> | --seeks=<output name> ]
@@ -943,6 +944,12 @@ Usage: btt 2.06
This option tells \texttt{btt} to generate the per IO dump file as
discussed in section~\ref{sec:per-io}.
+\subsection{\label{sec:o-P}\texttt{--per-io-tress}/\texttt{-P}}
+
+The \texttt{-P} option will generate a file that contains a list of all IO
+"sequences" - showing only the Q, D \& C operation times. The D \& C
+time values are separated from the Q time values with a vertical bar.
+
\subsection{\label{sec:o-q}\texttt{--q2c-latencies}/\texttt{-q}}
This option instructs \texttt{btt} to generate the Q2C latency file
diff --git a/btt/globals.h b/btt/globals.h
index a901b52..0ee06ed 100644
--- a/btt/globals.h
+++ b/btt/globals.h
@@ -148,7 +148,7 @@ struct d_info {
void *q2q_handle, *seek_handle, *bno_dump_handle, *unplug_hist_handle;
void *q2d_priv, *aqd_handle;
void *q2d_plat_handle, *q2c_plat_handle, *d2c_plat_handle;
- FILE *q2d_ofp, *d2c_ofp, *q2c_ofp;
+ FILE *q2d_ofp, *d2c_ofp, *q2c_ofp, *pit_fp;
struct avgs_info avgs;
struct stats stats, all_stats;
__u64 last_q, n_qs, n_ds;
@@ -182,6 +182,7 @@ struct io {
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 char *bno_dump_name, *unplug_hist_name, *sps_name, *aqd_name, *q2d_name;
+extern char *per_io_trees;
extern double range_delta, plat_freq;
extern FILE *ranges_ofp, *avgs_ofp, *xavgs_ofp, *iostat_ofp, *per_io_ofp;
extern FILE *msgs_ofp;
diff --git a/btt/trace_complete.c b/btt/trace_complete.c
index 35a6b17..6f616bc 100644
--- a/btt/trace_complete.c
+++ b/btt/trace_complete.c
@@ -53,6 +53,8 @@ static void handle_complete(struct io *c_iop)
{
LIST_HEAD(head);
struct list_head *p, *q;
+ __u64 d_time = (__u64)-1;
+ FILE *pit_fp = c_iop->dip->pit_fp;
update_blks(c_iop);
update_cregion(&all_regions, c_iop->t.time);
@@ -77,6 +79,8 @@ static void handle_complete(struct io *c_iop)
update_d2c(q_iop, d2c);
latency_d2c(q_iop->dip, c_iop->t.time, d2c);
iostat_complete(q_iop, c_iop);
+
+ d_time = q_iop->d_time;
}
if (per_io_ofp) {
@@ -86,6 +90,12 @@ static void handle_complete(struct io *c_iop)
display_io_track(per_io_ofp, q_iop);
}
+ if (q_iop->dip->pit_fp) {
+ fprintf(pit_fp, "%d.%09lu ",
+ (int)SECONDS(q_iop->t.time),
+ (unsigned long)NANO_SECONDS(q_iop->t.time));
+ }
+
list_del(&q_iop->f_head);
io_release(q_iop);
}
@@ -93,6 +103,14 @@ static void handle_complete(struct io *c_iop)
if (per_io_ofp)
fprintf(per_io_ofp,
"-----------------------------------------\n");
+
+ if (c_iop->dip->pit_fp) {
+ fprintf(pit_fp, "| %d.%09lu | %d.%09lu\n",
+ (int)SECONDS(d_time),
+ (unsigned long)NANO_SECONDS(d_time),
+ (int)SECONDS(c_iop->t.time),
+ (unsigned long)NANO_SECONDS(c_iop->t.time));
+ }
}
void trace_complete(struct io *c_iop)