Added -P to create a data file w/ Q, D and C per line
authorAlan D. Brunelle <alan.brunelle@hp.com>
Tue, 11 Nov 2008 18:46:13 +0000 (13:46 -0500)
committerAlan D. Brunelle <alan.brunelle@hp.com>
Tue, 11 Nov 2008 18:46:13 +0000 (13:46 -0500)
Easy parsing for graph creation

btt/args.c
btt/bt_timeline.c
btt/devs.c
btt/doc/btt.tex
btt/globals.h
btt/trace_complete.c
doc/btt.1

index 5555e4f10f70b43ea81dfb21b75786c354870f71..c648b9307db4975824f02eca6a1c6a65a724eba4 100644 (file)
@@ -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",
@@ -121,6 +121,12 @@ static struct option l_opts[] = {
                .flag = NULL,
                .val = 'p'
        },
+       {
+               .name = "per-io-trees",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'P'
+       },
        {
                .name = "q2c-latencies",
                .has_arg = required_argument,
@@ -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;
index 734ca350a7cfea0eb1bb97b36dcb4a1cf895cb64..dda46222a1163be6df88879a9ac0f992d2411630 100644 (file)
 #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;
index 6c9870ff3f0bfdf398abf97f3a1c7eb02e7fd419..e5304773087b413c0e5307a16b94caa9c4f0f40c 100644 (file)
@@ -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) {
index 5f7ef1cd2b2c1cf67b395a4fe7541168d677fa90..4f5997137c74d658534c829312e69ba45cbc2964 100644 (file)
@@ -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.0
 [ -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
index a901b52283d2d275b432bd765ca6c0da32121f01..0ee06ed0f0fe961121c3ec0a098f622f3f741435 100644 (file)
@@ -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;
index 35a6b17a714ff821d75d827854a4eaf54ca2988b..6f616bcab2499d80ff23af92e1cf18678f02122f 100644 (file)
@@ -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)
index 6f6fbdb2fc23cd34fee5ef86014108965456493e..fa437f9016d19577ee19fcc45165757626b47f46 100644 (file)
--- a/doc/btt.1
+++ b/doc/btt.1
@@ -35,6 +35,8 @@ btt \- analyse block i/o traces produces by blktrace
 .br
 [ \-p <\fIoutput name\fR> | \-\-per\-io\-dump=<\fIoutput name\fR> ]
 .br
+[ \-P <\fIoutput name\fR> | \-\-per\-io\-trees=<\fIoutput name\fR> ]
+.br
 [ \-q <\fIoutput name\fR> | \-\-q2c\-latencies=<\fIoutput name\fR> ]
 .br
 [ \-Q <\fIoutput name\fR> | \-\-active\-queue\-depth=<\fIoutput name\fR> ]
@@ -217,6 +219,15 @@ The \-p option will generate a file that contains a list of all IO
 "sequences" \- showing the parts of each IO (Q, A, I/M, D, & C).
 .RE
 
+.B \-P <\fIoutput name\fR>
+.br
+.B \-\-per\-io\-trees=<\fIoutput name\fR>
+.RS 4
+The \-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.
+.RE
+
 .B \-q <\fIoutput name\fR>
 .br
 .B \-\-q2c\-latencies=<\fIoutput name\fR>