\title{\texttt{btt} User Guide}
\author{Alan D. Brunelle (Alan.Brunelle@hp.com)}
-\date{12 February 2008}
+\date{9 May 2008}
\begin{document}
\maketitle
This is denoted as \emph{Q2I} time.
- This is also broken down into two component times:
+ This is also broken down into two component times\footnote{On
+ occasion there are also some time spent \emph{sleeping} waiting
+ for a request. That occurs between the Q and G operations. You
+ will see these listed as \texttt{S2G} times.}:
\begin{description}
\item[Q2G] Time needed to \emph{get} a request (get request
\newpage\section{\label{sec:cmd-line}Command Line}
\begin{verbatim}
-Usage: btt 2.03
+Usage: btt 2.04
[ -a | --seek-absolute ]
[ -A | --all-data ]
[ -B <output name> | --dump-blocknos=<output name> ]
\texttt{UPG} & Unplug Information:\\
& IOsPerUnplug IOsPerUnplugTimeout\\\hline
\texttt{ARQ} & Active Requests at Q Information:\\
- & AvgReqs@Q\\\hline
+ & AvgReqs@Q\\\hline\hline
+ \texttt{Q2Q} & Queue-to-Queue times:\\
+ \texttt{Q2G} & Queue-to-GetRequest times:\\
+ \texttt{S2G} & Sleep-to-GetRequest times:\\
+ \texttt{G2I} & GetRequest-to-Insert times:\\
+ \texttt{Q2M} & Queue-to-Merge times:\\
+ \texttt{I2D} & Insert-to-Issue times:\\
+ \texttt{M2D} & Merge-to-Issue times:\\
+ \texttt{D2C} & Issue-to-Complete times:\\
+ \texttt{Q2C} & Queue-to-Complete times:\\
+ & MIN AVG MAX N\\\hline
\end{tabular}
\bigskip
A sample output file would look like:
\begin{verbatim}
-DMI 8,16 310407 106729 2.908366049 0 182 1024 19504768
-QSK 8,16 310407 167141.958551192 0 0 235753
+Q2Q 0.000000001 0.003511356 9.700000000 309906
+Q2G 0.000000001 0.774586535 805.300000000 106732
+S2G 0.000000001 0.072525952 0.370000000 578
+G2I 0.000000001 0.000001125 0.010000000 106732
+Q2M 0.000000001 0.730763626 751.820000000 204040
+I2D 0.000000001 1.270720538 612.880000000 106948
+M2D 0.000000001 0.992355230 428.930000000 203114
+D2C 0.000000001 0.008681311 137.020000000 307343
+Q2C 0.000000001 1.304370794 805.660000000 308921
+DMI 8,16 309907 106729 2.903681286 8 182 1024 19504768
+QSK 8,16 309907 167200.935561314 0 0 235708
DSK 8,16 106729 433247.436563633 0 0 33974
-PLG 8,16 40824 382 0.008882101
+PLG 8,16 40824 382 0.008881420
UPG 8,16 1.993361748 1.866492147
-ARQ 8,16 22.863331046
+ARQ 8,16 12.938165321
\end{verbatim}
\newpage\section{\label{sec:bno_plot}bno\_plot.py}
ai_dip_t dip_q2c_avg(struct d_info *dip) { return &dip->avgs.q2c; }
ai_dip_t dip_q2a_avg(struct d_info *dip) { return &dip->avgs.q2a; }
ai_dip_t dip_q2g_avg(struct d_info *dip) { return &dip->avgs.q2g; }
+ai_dip_t dip_s2g_avg(struct d_info *dip) { return &dip->avgs.s2g; }
ai_dip_t dip_g2i_avg(struct d_info *dip) { return &dip->avgs.g2i; }
ai_dip_t dip_q2m_avg(struct d_info *dip) { return &dip->avgs.q2m; }
ai_dip_t dip_i2d_avg(struct d_info *dip) { return &dip->avgs.i2d; }
ai_pip_t pip_q2c_avg(struct p_info *pip) { return &pip->avgs.q2c; }
ai_pip_t pip_q2a_avg(struct p_info *pip) { return &pip->avgs.q2a; }
ai_pip_t pip_q2g_avg(struct p_info *pip) { return &pip->avgs.q2g; }
+ai_pip_t pip_s2g_avg(struct p_info *pip) { return &pip->avgs.s2g; }
ai_pip_t pip_g2i_avg(struct p_info *pip) { return &pip->avgs.g2i; }
ai_pip_t pip_q2m_avg(struct p_info *pip) { return &pip->avgs.q2m; }
ai_pip_t pip_i2d_avg(struct p_info *pip) { return &pip->avgs.i2d; }
fprintf(ofp, "--------------- ------------- ------------- ------------- -----------\n");
}
-void __output_avg(FILE *ofp, char *hdr, struct avg_info *ap)
+void __output_avg(FILE *ofp, char *hdr, struct avg_info *ap, int do_easy)
{
if (ap->n > 0) {
ap->avg = BIT_TIME(ap->total) / (double)ap->n;
fprintf(ofp, "%-15s %13.9f %13.9f %13.9f %11d\n", hdr,
BIT_TIME(ap->min), ap->avg, BIT_TIME(ap->max), ap->n);
+
+ if (do_easy && easy_parse_avgs) {
+ fprintf(xavgs_ofp,
+ "%s %.9lf %.9lf %.9lf %d\n",
+ hdr, BIT_TIME(ap->min), ap->avg,
+ BIT_TIME(ap->max), ap->n);
+ }
}
}
if (ap->n > 0) {
char dev_info[15];
ap->avg = BIT_TIME(ap->total) / (double)ap->n;
- __output_avg(odap->ofp, make_dev_hdr(dev_info, 15, dip), ap);
+ __output_avg(odap->ofp, make_dev_hdr(dev_info, 15, dip), ap, 0);
}
}
snprintf(proc_name, 15, pip->name);
ap->avg = BIT_TIME(ap->total) / (double)ap->n;
- __output_avg(opap->ofp, proc_name, ap);
+ __output_avg(opap->ofp, proc_name, ap, 0);
}
}
output_pip_avg(ofp, "Q2Q", pip_q2q_avg);
output_pip_avg(ofp, "Q2A", pip_q2a_avg);
output_pip_avg(ofp, "Q2G", pip_q2g_avg);
+ output_pip_avg(ofp, "S2G", pip_s2g_avg);
output_pip_avg(ofp, "G2I", pip_g2i_avg);
output_pip_avg(ofp, "Q2M", pip_q2m_avg);
output_pip_avg(ofp, "I2D", pip_i2d_avg);
output_dip_avg(ofp, "Q2Q", dip_q2q_avg);
output_dip_avg(ofp, "Q2A", dip_q2a_avg);
output_dip_avg(ofp, "Q2G", dip_q2g_avg);
+ output_dip_avg(ofp, "S2G", dip_s2g_avg);
output_dip_avg(ofp, "G2I", dip_g2i_avg);
output_dip_avg(ofp, "Q2M", dip_q2m_avg);
output_dip_avg(ofp, "I2D", dip_i2d_avg);
output_section_hdr(ofp, "All Devices");
output_hdr(ofp, "ALL");
- __output_avg(ofp, "Q2Qdm", &all_avgs.q2q_dm);
- __output_avg(ofp, "Q2Adm", &all_avgs.q2a_dm);
- __output_avg(ofp, "Q2Cdm", &all_avgs.q2c_dm);
+ __output_avg(ofp, "Q2Qdm", &all_avgs.q2q_dm, 0);
+ __output_avg(ofp, "Q2Adm", &all_avgs.q2a_dm, 0);
+ __output_avg(ofp, "Q2Cdm", &all_avgs.q2c_dm, 0);
fprintf(ofp, "\n");
- __output_avg(ofp, "Q2Q", &all_avgs.q2q);
- __output_avg(ofp, "Q2A", &all_avgs.q2a);
- __output_avg(ofp, "Q2G", &all_avgs.q2g);
- __output_avg(ofp, "G2I", &all_avgs.g2i);
- __output_avg(ofp, "Q2M", &all_avgs.q2m);
- __output_avg(ofp, "I2D", &all_avgs.i2d);
- __output_avg(ofp, "M2D", &all_avgs.m2d);
- __output_avg(ofp, "D2C", &all_avgs.d2c);
- __output_avg(ofp, "Q2C", &all_avgs.q2c);
+ __output_avg(ofp, "Q2Q", &all_avgs.q2q, 1);
+ __output_avg(ofp, "Q2A", &all_avgs.q2a, 1);
+ __output_avg(ofp, "Q2G", &all_avgs.q2g, 1);
+ __output_avg(ofp, "S2G", &all_avgs.s2g, 1);
+ __output_avg(ofp, "G2I", &all_avgs.g2i, 1);
+ __output_avg(ofp, "Q2M", &all_avgs.q2m, 1);
+ __output_avg(ofp, "I2D", &all_avgs.i2d, 1);
+ __output_avg(ofp, "M2D", &all_avgs.m2d, 1);
+ __output_avg(ofp, "D2C", &all_avgs.d2c, 1);
+ __output_avg(ofp, "Q2C", &all_avgs.q2c, 1);
fprintf(ofp, "\n");
output_section_hdr(ofp, "Device Overhead");
static void handle_g(struct io *g_iop)
{
- struct io *q_iop = dip_find_sec(g_iop->dip, IOP_Q, g_iop->t.sector);
+ struct io *q_iop;
iostat_getrq(g_iop);
+
+ q_iop = dip_find_sec(g_iop->dip, IOP_Q, g_iop->t.sector);
if (q_iop) {
q_iop->g_time = g_iop->t.time;
update_q2g(q_iop, tdelta(q_iop->t.time, g_iop->t.time));
+ if (q_iop->s_time != 0)
+ update_s2g(q_iop, tdelta(q_iop->s_time, g_iop->t.time));
}
}
+static void handle_s(struct io *s_iop)
+{
+ struct io *q_iop = dip_find_sec(s_iop->dip, IOP_Q, s_iop->t.sector);
+
+ if (q_iop)
+ q_iop->s_time = s_iop->t.time;
+}
+
static void handle_i(struct io *i_iop)
{
struct io *q_iop = dip_find_sec(i_iop->dip, IOP_Q, i_iop->t.sector);
static void handle_m(struct io *m_iop)
{
- struct io *q_iop = dip_find_sec(m_iop->dip, IOP_Q, m_iop->t.sector);
+ struct io *q_iop;
iostat_merge(m_iop);
+
+ q_iop = dip_find_sec(m_iop->dip, IOP_Q, m_iop->t.sector);
if (q_iop) {
q_iop->m_time = m_iop->t.time;
update_q2m(q_iop, tdelta(q_iop->t.time, m_iop->t.time));
m_iop->dip->n_act_q--;
}
+void trace_sleeprq(struct io *s_iop)
+{
+ if (s_iop->t.bytes == 0)
+ return;
+ if (io_setup(s_iop, IOP_S))
+ handle_s(s_iop);
+ io_release(s_iop);
+}
+
void trace_getrq(struct io *g_iop)
{
+ if (g_iop->t.bytes == 0)
+ return;
if (io_setup(g_iop, IOP_G))
handle_g(g_iop);
-
io_release(g_iop);
}
void trace_insert(struct io *i_iop)
{
+ if (i_iop->t.bytes == 0)
+ return;
if (io_setup(i_iop, IOP_I))
handle_i(i_iop);
-
io_release(i_iop);
}
void trace_merge(struct io *m_iop)
{
+ if (m_iop->t.bytes == 0)
+ return;
if (io_setup(m_iop, IOP_M))
handle_m(m_iop);
-
io_release(m_iop);
}