\title{\texttt{btt} User Guide}
\author{Alan D. Brunelle (Alan.Brunelle@hp.com)}
-\date{16 April 2007}
+\date{13 November 2007}
\begin{document}
\maketitle
\bigskip
This document refers to the output formats generated by \texttt{btt}
- version 0.99.1. However, the descriptions are general enough to cover
+ version 2.00. However, the descriptions are general enough to cover
output formats prior to that.
\newpage\tableofcontents
The total number of unplugs is equal to the number of plugs less the
ones due to timer unplugs.
+
+ \item[Active Requests At Q Information]
+
+ An important consideration when analyzing block IO schedulers is to
+ know how many requests the scheduler has to work with. The metric
+ provided in this section details how many requests (on average) were
+ being held by the IO scheduler when an incoming IO request was being
+ handled. To determine this, \texttt{btt} keeps track of how many Q
+ requests came in, and subtacts requests that have been issued (D).
+
+ Here is a sample output of this sections:
+
+\begin{verbatim}
+==================== Active Requests At Q Information ====================
+
+ DEV | Avg Reqs @ Q
+---------- | -------------
+ ( 65, 80) | 12.0
+ ( 65,240) | 16.9
+...
+ ( 66,112) | 44.2
+---------- | -------------
+ Overall | Avgs Reqs @ Q
+ Average | 17.4
+\end{verbatim}
+
\end{description}
\newpage
\newpage\section{\label{sec:cmd-line}Command Line}
\begin{verbatim}
-Usage: \texttt{btt} 0.99.1
+Usage: btt 2.00
[ -a | --seek-absolute ]
[ -A | --all-data ]
[ -B <output name> | --dump-blocknos=<output name> ]
struct avgs_info avgs;
struct stats stats, all_stats;
__u64 last_q, n_qs, n_ds;
+ __u64 n_act_q, t_act_q; /* # currently active when Q comes in */
__u32 device;
int pre_culling;
fprintf(ofp, "\n");
}
+int n_actQs;
+struct actQ_info {
+ __u64 t_qs;
+ __u64 t_act_qs;
+} actQ_info;
+
+void __dip_output_actQ(struct d_info *dip, void *arg)
+{
+ if (dip->n_qs > 0 && !remapper_dev(dip->device)) {
+ char dev_info[15];
+ double a_actQs = (double)dip->t_act_q / (double)dip->n_qs;
+
+ fprintf((FILE *)arg, "%10s | %13.1lf\n",
+ make_dev_hdr(dev_info, 15, dip), a_actQs);
+
+ n_actQs++;
+ actQ_info.t_qs += dip->n_qs;
+ actQ_info.t_act_qs += dip->t_act_q;
+ }
+}
+
+void __dip_output_actQ_all(FILE *ofp, struct actQ_info *p)
+{
+ fprintf(ofp, "---------- | -------------\n");
+ fprintf(ofp, "%10s | %13s\n", "Overall", "Avgs Reqs @ Q");
+ fprintf(ofp, "%10s | %13.1lf\n", "Average",
+ (double)p->t_act_qs / (double)p->t_qs);
+}
+
+void output_actQ_info(FILE *ofp)
+{
+ fprintf(ofp, "%10s | %13s\n", "DEV", "Avg Reqs @ Q");
+ fprintf(ofp, "---------- | -------------\n");
+ dip_foreach_out(__dip_output_actQ, ofp);
+ if (n_actQs > 1)
+ __dip_output_actQ_all(ofp, &actQ_info);
+ fprintf(ofp, "\n");
+}
+
void output_histos(void)
{
int i;
output_section_hdr(ofp, "Plug Information");
output_plug_info(ofp);
+ output_section_hdr(ofp, "Active Requests At Q Information");
+ output_actQ_info(ofp);
+
output_histos();
return 0;
LIST_HEAD(head);
struct list_head *p, *q;
+ if (d_iop->dip->n_act_q != 0)
+ d_iop->dip->n_act_q--;
+
seeki_add(d_iop->dip->seek_handle, d_iop);
bno_dump_add(d_iop->dip->bno_dump_handle, d_iop);
iostat_issue(d_iop);
q_iop->i_time = q_iop->gm_time = q_iop->d_time = (__u64)-1;
q_iop->is_getrq = -1;
q_iop->dip->n_qs++;
+
+ q_iop->dip->t_act_q += q_iop->dip->n_act_q;
+ q_iop->dip->n_act_q++;
}
void trace_queue(struct io *q_iop)