diff options
author | Alan D. Brunelle <Alan.Brunelle@hp.com> | 2007-12-10 13:41:37 -0500 |
---|---|---|
committer | Alan D. Brunelle <Alan.Brunelle@hp.com> | 2007-12-10 13:41:37 -0500 |
commit | ae6d30f4475181d685d1f33faf056755803f189b (patch) | |
tree | 461cfc69aacbe6536798af8291f55c3872442b1c /btt | |
parent | a84a97fdf8ce07ccda8dcc4f32f0df2291f2f54f (diff) | |
download | blktrace-ae6d30f4475181d685d1f33faf056755803f189b.tar.gz blktrace-ae6d30f4475181d685d1f33faf056755803f189b.tar.bz2 |
Separated out g/i/m trace handling.
Also separated out DM-device calculations.
Diffstat (limited to 'btt')
-rw-r--r-- | btt/bt_timeline.c | 2 | ||||
-rw-r--r-- | btt/doc/btt.tex | 46 | ||||
-rw-r--r-- | btt/globals.h | 19 | ||||
-rw-r--r-- | btt/inlines.h | 82 | ||||
-rw-r--r-- | btt/iostat.c | 17 | ||||
-rw-r--r-- | btt/output.c | 209 | ||||
-rw-r--r-- | btt/proc.c | 7 | ||||
-rw-r--r-- | btt/trace_complete.c | 22 | ||||
-rw-r--r-- | btt/trace_im.c | 52 | ||||
-rw-r--r-- | btt/trace_issue.c | 6 | ||||
-rw-r--r-- | btt/trace_queue.c | 11 |
11 files changed, 305 insertions, 168 deletions
diff --git a/btt/bt_timeline.c b/btt/bt_timeline.c index f67c2ad..b1f480a 100644 --- a/btt/bt_timeline.c +++ b/btt/bt_timeline.c @@ -25,7 +25,7 @@ #include <time.h> #include "globals.h" -char bt_timeline_version[] = "2.00"; +char bt_timeline_version[] = "2.01"; char *devices, *exes, *input_name, *output_name, *seek_name, *bno_dump_name; char *d2c_name, *q2c_name, *per_io_name, *unplug_hist_name; diff --git a/btt/doc/btt.tex b/btt/doc/btt.tex index 3d3abd2..0fe44ef 100644 --- a/btt/doc/btt.tex +++ b/btt/doc/btt.tex @@ -29,7 +29,9 @@ %-------------- \section{\label{sec:intro}Introduction} -\texttt{btt} is a post-processing tool for the block layer IO tracing tool called blktrace. As noted in its Users Guide, blktrace +\texttt{btt} is a post-processing tool for the block layer IO tracing +tool called blktrace. As noted in its Users Guide, blktrace + \begin{quotation} is a block layer IO tracing mechanism which provides detailed information about request queue operations up to user space. @@ -109,11 +111,24 @@ easier. \begin{enumerate} \item Time needed to insert or merge an incoming IO onto the request queue. This is the average time from when the IO enters the block - IO layer (queue trace) until it is inserted (insert trace) or merged - (back merge or front merge trace). + IO layer (queue trace) until it is inserted (insert trace). This is denoted as \emph{Q2I} time. + This is also broken down into two component times: + + \begin{description} + \item[Q2G] Time needed to \emph{get} a request (get request + trace). + + \item[G2I] Time needed to put that request onto the request + queue (insert trace). + \end{description} + + For \emph{merged} requests -- an incoming request that is merged + with a previously submitted request -- we calculate \emph{Q2M}, the + amount of time between the queue trace and the merge trace. + \item Time spent on the request queue. The average time from when the IO is inserted or merged onto the request queue, until it is issued (issue trace) to the lower level driver. @@ -163,16 +178,31 @@ D2C 0.000193721 0.030406554 1.634221408 2262311 Q2C 0.000207665 0.125405263 1.830917198 2262311 \end{verbatim} + When tracking \emph{device mapper} devices, we also break down the + \emph{Q2A} and \emph{Q2C} times for those IOs. + \item[Device Overhead] Using the data from the previous chart, we can then provide some idea as to where IO spend most of the time on average. The following output - shows the percentage of time spent in each of the 3 phases of an IO: + shows the percentage of time spent in each of the phases of an +IO\footnote{It should be noted that incoming requests either go through: + +\begin{enumerate} + \item Q2G + Q2I + + or + + \item Q2M +\end{enumerate} + before proceeding to I2D and D2C.} \begin{verbatim} - DEV | Q2I I2D D2C ----------- | ------ ------ ------ - ( 68, 64) | 0.0% 75.7% 24.2% + DEV | Q2G G2I Q2M I2D D2C +---------- | --------- --------- --------- --------- --------- + ( 8, 80) | 0.0013% 0.0004% 0.0006% 88.5005% 11.4988% +---------- | --------- --------- --------- --------- --------- + Overall | 0.0003% 0.0001% 0.0041% 21.4998% 78.4958% \end{verbatim} \item[Device Merge Information] @@ -693,7 +723,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.00 +Usage: btt 2.01 [ -a | --seek-absolute ] [ -A | --all-data ] [ -B <output name> | --dump-blocknos=<output name> ] diff --git a/btt/globals.h b/btt/globals.h index 4e8edc6..4176fb4 100644 --- a/btt/globals.h +++ b/btt/globals.h @@ -106,12 +106,19 @@ struct avg_info { }; struct avgs_info { + struct avg_info q2q_dm; + struct avg_info q2a_dm; + struct avg_info q2c_dm; + struct avg_info q2q; - struct avg_info q2c; - struct avg_info q2a; /* Q to (A or X) */ - struct avg_info q2i; /* Q to (I or M) */ - struct avg_info i2d; /* (I or M) to D */ + struct avg_info q2a; + struct avg_info q2g; + struct avg_info g2i; + struct avg_info q2m; + struct avg_info i2d; + struct avg_info m2d; struct avg_info d2c; + struct avg_info q2c; struct avg_info blks; /* Blocks transferred */ }; @@ -178,12 +185,12 @@ struct io { struct d_info *dip; struct p_info *pip; void *pdu; - __u64 bytes_left, i_time, gm_time, d_time, c_time, d_sec, c_sec; + __u64 bytes_left, g_time, i_time, m_time, d_time, c_time, d_sec, c_sec; __u32 d_nsec, c_nsec; struct blk_io_trace t; - int linked, is_getrq; + int linked; enum iop_type type; #if defined(COUNT_IOS) diff --git a/btt/inlines.h b/btt/inlines.h index 43dada0..875b75b 100644 --- a/btt/inlines.h +++ b/btt/inlines.h @@ -19,6 +19,12 @@ * */ +static inline int remapper_dev(__u32 dev) +{ + int mjr = MAJOR(dev); + return mjr == 9 || mjr == 253 || mjr == 254; +} + static inline void region_init(struct region_info *reg) { INIT_LIST_HEAD(®->qranges); @@ -118,7 +124,10 @@ static inline void update_lq(__u64 *last_q, struct avg_info *avg, __u64 time) static inline void dip_update_q(struct d_info *dip, struct io *iop) { - update_lq(&dip->last_q, &dip->avgs.q2q, iop->t.time); + if (remapper_dev(dip->device)) + update_lq(&dip->last_q, &dip->avgs.q2q_dm, iop->t.time); + else + update_lq(&dip->last_q, &dip->avgs.q2q, iop->t.time); update_qregion(&dip->regions, iop->t.time); } @@ -228,7 +237,10 @@ static inline void update_q2c(struct io *iop, __u64 c_time) if (per_io_ofp) fprintf(per_io_ofp, "q2c %13.9f\n", BIT_TIME(c_time)); # endif - UPDATE_AVGS(q2c, iop, iop->pip, c_time); + if (remapper_dev(iop->dip->device)) + UPDATE_AVGS(q2c_dm, iop, iop->pip, c_time); + else + UPDATE_AVGS(q2c, iop, iop->pip, c_time); } static inline void update_q2a(struct io *iop, __u64 a_time) @@ -237,22 +249,55 @@ static inline void update_q2a(struct io *iop, __u64 a_time) if (per_io_ofp) fprintf(per_io_ofp, "q2a %13.9f\n", BIT_TIME(a_time)); # endif - UPDATE_AVGS(q2a, iop, iop->pip, a_time); + if (remapper_dev(iop->dip->device)) + UPDATE_AVGS(q2a_dm, iop, iop->pip, a_time); + else + UPDATE_AVGS(q2a, iop, iop->pip, a_time); +} + +static inline void update_q2g(struct io *iop, __u64 g_time) +{ +# if defined(DEBUG) + if (per_io_ofp) + fprintf(per_io_ofp, "q2g %13.9f\n", BIT_TIME(g_time)); +# endif + + UPDATE_AVGS(q2g, iop, iop->pip, g_time); +} + +static inline void unupdate_q2g(struct io *iop, __u64 g_time) +{ + UNUPDATE_AVGS(q2g, iop, iop->pip, g_time); +} + +static inline void update_g2i(struct io *iop, __u64 i_time) +{ +# if defined(DEBUG) + if (per_io_ofp) + fprintf(per_io_ofp, "g2i %13.9f\n", BIT_TIME(i_time)); +# endif + + UPDATE_AVGS(g2i, iop, iop->pip, i_time); +} + +static inline void unupdate_g2i(struct io *iop, __u64 i_time) +{ + UNUPDATE_AVGS(g2i, iop, iop->pip, i_time); } -static inline void update_q2i(struct io *iop, __u64 i_time) +static inline void update_q2m(struct io *iop, __u64 m_time) { # if defined(DEBUG) if (per_io_ofp) - fprintf(per_io_ofp, "q2i %13.9f\n", BIT_TIME(i_time)); + fprintf(per_io_ofp, "q2m %13.9f\n", BIT_TIME(m_time)); # endif - UPDATE_AVGS(q2i, iop, iop->pip, i_time); + UPDATE_AVGS(q2m, iop, iop->pip, m_time); } -static inline void unupdate_q2i(struct io *iop, __u64 i_time) +static inline void unupdate_q2m(struct io *iop, __u64 m_time) { - UNUPDATE_AVGS(q2i, iop, iop->pip, i_time); + UNUPDATE_AVGS(q2m, iop, iop->pip, m_time); } static inline void update_i2d(struct io *iop, __u64 d_time) @@ -270,6 +315,21 @@ static inline void unupdate_i2d(struct io *iop, __u64 d_time) UNUPDATE_AVGS(i2d, iop, iop->pip, d_time); } +static inline void update_m2d(struct io *iop, __u64 d_time) +{ +# if defined(DEBUG) + if (per_io_ofp) + fprintf(per_io_ofp, "m2d %13.9f\n", BIT_TIME(d_time)); +# endif + + UPDATE_AVGS(m2d, iop, iop->pip, d_time); +} + +static inline void unupdate_m2d(struct io *iop, __u64 d_time) +{ + UNUPDATE_AVGS(m2d, iop, iop->pip, d_time); +} + static inline void update_d2c(struct io *iop, __u64 c_time) { # if defined(DEBUG) @@ -329,12 +389,6 @@ static inline __u64 tdelta(__u64 from, __u64 to) return (from < to) ? (to - from) : 1; } -static inline int remapper_dev(__u32 dev) -{ - int mjr = MAJOR(dev); - return mjr == 9 || mjr == 253 || mjr == 254; -} - static inline int type2c(enum iop_type type) { int c; diff --git a/btt/iostat.c b/btt/iostat.c index 785029d..f46d572 100644 --- a/btt/iostat.c +++ b/btt/iostat.c @@ -60,11 +60,6 @@ void dump_hdr(void) "avgrq-sz avgqu-sz await svctm %%util Stamp\n"); } -void im2d2c_func(struct io *c_iop, struct io *im_iop) -{ - ADD_STAT(c_iop->dip, wait, tdelta(im_iop->t.time, c_iop->t.time)); -} - void iostat_init(void) { last_start = (__u64)-1; @@ -281,13 +276,15 @@ void iostat_unissue(struct io *iop) DEC_STAT(dip, cur_dev); } -void iostat_complete(struct io *d_iop, struct io *c_iop) +void iostat_complete(struct io *q_iop, struct io *c_iop) { double now = TO_SEC(c_iop->t.time); - struct d_info *dip = d_iop->dip; + struct d_info *dip = q_iop->dip; - dip_foreach(d_iop, IOP_I, im2d2c_func, 0); - dip_foreach(d_iop, IOP_M, im2d2c_func, 0); + if (q_iop->i_time != (__u64)-1) + ADD_STAT(c_iop->dip, wait, tdelta(q_iop->i_time,c_iop->t.time)); + else if (q_iop->m_time != (__u64)-1) + ADD_STAT(c_iop->dip, wait, tdelta(q_iop->m_time,c_iop->t.time)); update_tot_qusz(dip, now); DEC_STAT(dip, cur_qusz); @@ -295,5 +292,5 @@ void iostat_complete(struct io *d_iop, struct io *c_iop) update_idle_time(dip, now, 0); DEC_STAT(dip, cur_dev); - ADD_STAT(dip, svctm, tdelta(d_iop->t.time, c_iop->t.time)); + ADD_STAT(dip, svctm, tdelta(q_iop->t.time, c_iop->t.time)); } diff --git a/btt/output.c b/btt/output.c index 787de70..33a9a73 100644 --- a/btt/output.c +++ b/btt/output.c @@ -22,18 +22,30 @@ #include "globals.h" typedef struct avg_info *ai_dip_t; +ai_dip_t dip_q2q_dm_avg(struct d_info *dip) { return &dip->avgs.q2q_dm; } +ai_dip_t dip_q2a_dm_avg(struct d_info *dip) { return &dip->avgs.q2a_dm; } +ai_dip_t dip_q2c_dm_avg(struct d_info *dip) { return &dip->avgs.q2c_dm; } + ai_dip_t dip_q2q_avg(struct d_info *dip) { return &dip->avgs.q2q; } 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_q2i_avg(struct d_info *dip) { return &dip->avgs.q2i; } +ai_dip_t dip_q2g_avg(struct d_info *dip) { return &dip->avgs.q2g; } +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_dip_t dip_d2c_avg(struct d_info *dip) { return &dip->avgs.d2c; } typedef struct avg_info *ai_pip_t; +ai_pip_t pip_q2q_dm_avg(struct p_info *pip) { return &pip->avgs.q2q_dm; } +ai_pip_t pip_q2a_dm_avg(struct p_info *pip) { return &pip->avgs.q2a_dm; } +ai_pip_t pip_q2c_dm_avg(struct p_info *pip) { return &pip->avgs.q2c_dm; } + ai_pip_t pip_q2q_avg(struct p_info *pip) { return &pip->avgs.q2q; } 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_q2i_avg(struct p_info *pip) { return &pip->avgs.q2i; } +ai_pip_t pip_q2g_avg(struct p_info *pip) { return &pip->avgs.q2g; } +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; } ai_pip_t pip_d2c_avg(struct p_info *pip) { return &pip->avgs.d2c; } @@ -60,12 +72,6 @@ void __output_avg(FILE *ofp, char *hdr, struct avg_info *ap) } } -void output_hdr2(FILE *ofp, char*hdr) -{ - fprintf(ofp, "%15s %13s %13s %13s %13s %13s %13s\n", hdr, "Q2Q", "Q2A", "Q2I", "I2D", "D2C", "Q2C"); - fprintf(ofp, "--------------- ------------- ------------- ------------- ------------- ------------- -------------\n"); -} - static inline char *avg2string(struct avg_info *ap, char *string) { if (ap->n > 0) @@ -75,30 +81,6 @@ static inline char *avg2string(struct avg_info *ap, char *string) return string; } -void __output_avg2(FILE *ofp, char *hdr, struct avgs_info *ap) -{ - char c1[16], c2[16], c3[16], c4[16], c5[16], c6[16]; - - if (ap->q2q.n > 0 || ap->q2a.n > 0 || ap->q2i.n > 0 || - ap->i2d.n > 0 || ap->d2c.n > 0 || ap->q2c.n > 0) { - fprintf(ofp, "%-15s %13s %13s %13s %13s %13s %13s\n", hdr, - avg2string(&ap->q2q,c1), avg2string(&ap->q2a,c2), - avg2string(&ap->q2i,c3), avg2string(&ap->i2d,c4), - avg2string(&ap->d2c,c5), avg2string(&ap->q2c,c6)); - } -} - -void __pip_output_avg2(struct p_info *pip, void *arg) -{ - __output_avg2((FILE *)arg, pip->name, &pip->avgs); -} - -void __dip_output_avg2(struct d_info *dip, void *arg) -{ - char dev_info[15]; - __output_avg2((FILE *)arg, make_dev_hdr(dev_info, 15, dip), &dip->avgs); -} - char *make_dev_hdr(char *pad, size_t len, struct d_info *dip) { if (dip->map == NULL) @@ -244,69 +226,110 @@ void output_dip_merge_ratio(FILE *ofp) fprintf(ofp, "\n"); } +struct __ohead_data { + __u64 total; + int n; +}; + +struct ohead_data { + FILE *ofp; + struct __ohead_data q2g, g2i, q2m, i2d, d2c; +}; + #define AVG(a,b) (100.0 * ((double)(a) / (double)(b))) #define CALC_AVG(ap) (ap)->avg = ((ap)->n == 0 ? 0.0 : \ (BIT_TIME((ap)->total) / \ (double)(ap)->n)) -char *q2i_v_q2C(struct d_info *dip, char *s) -{ - double q2c; - - if (dip->avgs.q2i.n == 0) return " "; - - q2c = dip->avgs.q2i.avg + dip->avgs.i2d.avg + dip->avgs.d2c.avg; - sprintf(s, "%5.1lf%%", AVG(dip->avgs.q2i.avg, q2c)); +#define x_v_q2C(fld, dip, s, odp) \ + double q2c; \ + if (dip->avgs. fld .n == 0) return " "; \ + q2c = dip->avgs.g2i.avg + dip->avgs.g2i.avg + \ + dip->avgs.i2d.avg + dip->avgs.d2c.avg; \ + sprintf(s, "%8.4lf%%", AVG(dip->avgs. fld .avg, q2c)); \ + odp-> fld .n += dip->avgs. fld .n; \ + odp-> fld .total += dip->avgs. fld .total; \ return s; -} -char *i2d_v_q2C(struct d_info *dip, char *s) +char *q2g_v_q2C(struct d_info *dip, char *s, struct ohead_data *odp) { - double q2c; - - if (dip->avgs.d2c.n == 0) return " "; - - q2c = dip->avgs.q2i.avg + dip->avgs.i2d.avg + dip->avgs.d2c.avg; - sprintf(s, "%5.1lf%%", AVG(dip->avgs.i2d.avg, q2c)); - - return s; + x_v_q2C(q2g, dip, s, odp); } -char *d2c_v_q2C(struct d_info *dip, char *s) +char *g2i_v_q2C(struct d_info *dip, char *s, struct ohead_data *odp) { - double q2c; + x_v_q2C(g2i, dip, s, odp); +} - if (dip->avgs.d2c.n == 0) return " "; +char *q2m_v_q2C(struct d_info *dip, char *s, struct ohead_data *odp) +{ + x_v_q2C(q2m, dip, s, odp); +} - q2c = dip->avgs.q2i.avg + dip->avgs.i2d.avg + dip->avgs.d2c.avg; - sprintf(s, "%5.1lf%%", AVG(dip->avgs.d2c.avg, q2c)); +char *i2d_v_q2C(struct d_info *dip, char *s, struct ohead_data *odp) +{ + x_v_q2C(i2d, dip, s, odp); +} - return s; +char *d2c_v_q2C(struct d_info *dip, char *s, struct ohead_data *odp) +{ + x_v_q2C(d2c, dip, s, odp); } void __output_dip_prep_ohead(struct d_info *dip, void *arg) { char dev_info[15]; - char s1[16], s2[16], s3[16]; - - if ((dip->avgs.q2i.n > 0 && dip->avgs.i2d.n > 0 && - dip->avgs.d2c.n > 0)) { - CALC_AVG(&dip->avgs.q2i); + char s1[16], s2[16], s3[16], s4[16], s5[16]; + struct ohead_data *odp = arg; + + if (dip->avgs.q2g.n > 0 && dip->avgs.g2i.n > 0 && + dip->avgs.i2d.n > 0 && dip->avgs.d2c.n > 0) { + CALC_AVG(&dip->avgs.q2g); + CALC_AVG(&dip->avgs.g2i); + CALC_AVG(&dip->avgs.q2m); CALC_AVG(&dip->avgs.i2d); CALC_AVG(&dip->avgs.d2c); - fprintf((FILE *)arg, "%10s | %6s %6s %6s\n", + fprintf(odp->ofp, "%10s | %9s %9s %9s %9s %9s\n", make_dev_hdr(dev_info, 15, dip), - q2i_v_q2C(dip, s1), i2d_v_q2C(dip, s2), - d2c_v_q2C(dip, s3)); + q2g_v_q2C(dip, s1, odp), + g2i_v_q2C(dip, s2, odp), + q2m_v_q2C(dip, s3, odp), + i2d_v_q2C(dip, s4, odp), + d2c_v_q2C(dip, s5, odp)); } } +#define OD_AVG(od, fld, q2c) \ + (od. fld .n == 0) ? (double)0.0 : \ + (100.0 * ((double)((od). fld . total) / q2c)) + void output_dip_prep_ohead(FILE *ofp) { - fprintf(ofp, "%10s | %6s %6s %6s\n", "DEV", "Q2I", "I2D", "D2C"); - fprintf(ofp, "---------- | ------ ------ ------\n"); - dip_foreach_out(__output_dip_prep_ohead, ofp); + double q2c; + struct ohead_data od; + + memset(&od, 0, sizeof(od)); + od.ofp = ofp; + + fprintf(ofp, "%10s | %9s %9s %9s %9s %9s\n", + "DEV", "Q2G", "G2I", "Q2M", "I2D", "D2C"); + fprintf(ofp, "---------- | --------- --------- --------- --------- ---------\n"); + dip_foreach_out(__output_dip_prep_ohead, &od); + + if (od.q2g.n == 0 && od.g2i.n == 0 && od.q2m.n == 0 && + od.i2d.n == 0 && od.d2c.n == 0) + goto out; + + q2c = od.q2g.total + od.g2i.total + od.q2m.total + + od.i2d.total + od.d2c.total; + fprintf(ofp, "---------- | --------- --------- --------- --------- ---------\n"); + fprintf(ofp, "%10s | %8.4lf%% %8.4lf%% %8.4lf%% %8.4lf%% %8.4lf%%\n", "Overall", + OD_AVG(od, q2g, q2c), OD_AVG(od, g2i, q2c), + OD_AVG(od, q2m, q2c), OD_AVG(od, i2d, q2c), + OD_AVG(od, d2c, q2c)); + +out: fprintf(ofp, "\n"); } @@ -489,20 +512,6 @@ void output_pip_avg(FILE *ofp, char *hdr, ai_pip_t (*func)(struct p_info *)) fprintf(ofp, "\n"); } -void output_dip_avgs(FILE *ofp) -{ - output_hdr2(ofp,"Dev"); - dip_foreach_out(__dip_output_avg2, ofp); - fprintf(ofp, "\n"); -} - -void output_pip_avgs(FILE *ofp) -{ - output_hdr2(ofp,"Exe"); - pip_foreach_out(__pip_output_avg2, ofp); - fprintf(ofp, "\n"); -} - int n_plugs; struct plug_info { long n_plugs, n_timer_unplugs; @@ -634,18 +643,32 @@ int output_avgs(FILE *ofp) if (output_all_data) { if (exes == NULL || *exes != '\0') { output_section_hdr(ofp, "Per Process"); + output_pip_avg(ofp, "Q2Qdm", pip_q2q_dm_avg); + output_pip_avg(ofp, "Q2Adm", pip_q2a_dm_avg); + output_pip_avg(ofp, "Q2Cdm", pip_q2c_dm_avg); + fprintf(ofp, "\n"); + output_pip_avg(ofp, "Q2Q", pip_q2q_avg); output_pip_avg(ofp, "Q2A", pip_q2a_avg); - output_pip_avg(ofp, "Q2I", pip_q2i_avg); + output_pip_avg(ofp, "Q2G", pip_q2g_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_pip_avg(ofp, "D2C", pip_d2c_avg); output_pip_avg(ofp, "Q2C", pip_q2c_avg); } output_section_hdr(ofp, "Per Device"); + output_dip_avg(ofp, "Q2Qdm", dip_q2q_dm_avg); + output_dip_avg(ofp, "Q2Adm", dip_q2a_dm_avg); + output_dip_avg(ofp, "Q2Cdm", dip_q2c_dm_avg); + fprintf(ofp, "\n"); + output_dip_avg(ofp, "Q2Q", dip_q2q_avg); output_dip_avg(ofp, "Q2A", dip_q2a_avg); - output_dip_avg(ofp, "Q2I", dip_q2i_avg); + output_dip_avg(ofp, "Q2G", dip_q2g_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_dip_avg(ofp, "D2C", dip_d2c_avg); output_dip_avg(ofp, "Q2C", dip_q2c_avg); @@ -653,10 +676,18 @@ int output_avgs(FILE *ofp) 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); + fprintf(ofp, "\n"); + __output_avg(ofp, "Q2Q", &all_avgs.q2q); __output_avg(ofp, "Q2A", &all_avgs.q2a); - __output_avg(ofp, "Q2I", &all_avgs.q2i); + __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); fprintf(ofp, "\n"); @@ -664,16 +695,6 @@ int output_avgs(FILE *ofp) output_section_hdr(ofp, "Device Overhead"); output_dip_prep_ohead(ofp); - if (output_all_data) { - if (exes == NULL || *exes != '\0') { - output_section_hdr(ofp, "Per Process (avgs)"); - output_pip_avgs(ofp); - } - - output_section_hdr(ofp, "Per Device (avgs)"); - output_dip_avgs(ofp); - } - output_section_hdr(ofp, "Device Merge Information"); output_dip_merge_ratio(ofp); @@ -214,7 +214,12 @@ void add_process(__u32 pid, char *name) void pip_update_q(struct io *iop) { if (iop->pip) { - update_lq(&iop->pip->last_q, &iop->pip->avgs.q2q, iop->t.time); + if (remapper_dev(iop->dip->device)) + update_lq(&iop->pip->last_q, &iop->pip->avgs.q2q_dm, + iop->t.time); + else + update_lq(&iop->pip->last_q, &iop->pip->avgs.q2q, + iop->t.time); update_qregion(&iop->pip->regions, iop->t.time); } } diff --git a/btt/trace_complete.c b/btt/trace_complete.c index c51d43d..b4dcadd 100644 --- a/btt/trace_complete.c +++ b/btt/trace_complete.c @@ -36,9 +36,14 @@ static void display_io_track(FILE *ofp, struct io *iop) { fprintf(ofp, "%3d,%-3d: ", MAJOR(iop->t.device), MINOR(iop->t.device)); __out(ofp, iop->t.time, IOP_Q, iop->t.sector, t_sec(&iop->t), 0); - __out(ofp, iop->i_time, IOP_I, iop->t.sector, t_sec(&iop->t), 1); - __out(ofp, iop->gm_time, iop->is_getrq ? IOP_G : IOP_M, - iop->t.sector, t_sec(&iop->t), 1); + + if (iop->g_time != (__u64)-1) + __out(ofp, iop->g_time, IOP_G, iop->t.sector, t_sec(&iop->t),1); + if (iop->i_time != (__u64)-1) + __out(ofp, iop->i_time, IOP_I, iop->t.sector, t_sec(&iop->t),1); + if (iop->m_time != (__u64)-1) + __out(ofp, iop->i_time, IOP_M, iop->t.sector, t_sec(&iop->t),1); + __out(ofp, iop->d_time, IOP_D, iop->d_sec, iop->d_nsec, 1); __out(ofp, iop->c_time, IOP_C, iop->c_sec, iop->c_nsec, 1); fprintf(ofp, "\n"); @@ -59,16 +64,19 @@ static void handle_complete(struct io *c_iop) list_for_each_safe(p, q, &head) { struct io *q_iop = list_entry(p, struct io, f_head); __u64 q2c = tdelta(q_iop->t.time, c_iop->t.time); - __u64 d2c = tdelta(q_iop->d_time, c_iop->t.time); c_iop->bytes_left -= q_iop->t.bytes; update_q2c(q_iop, q2c); latency_q2c(q_iop->dip, q_iop->t.time, q2c); - update_d2c(q_iop, d2c); - latency_d2c(q_iop->dip, c_iop->t.time, d2c); - iostat_complete(q_iop, c_iop); + if (q_iop->d_time != (__u64)-1) { + __u64 d2c = tdelta(q_iop->d_time, c_iop->t.time); + + update_d2c(q_iop, d2c); + latency_d2c(q_iop->dip, c_iop->t.time, d2c); + iostat_complete(q_iop, c_iop); + } if (per_io_ofp) { q_iop->c_time = c_iop->t.time; diff --git a/btt/trace_im.c b/btt/trace_im.c index f97c59b..c30b4ec 100644 --- a/btt/trace_im.c +++ b/btt/trace_im.c @@ -20,51 +20,59 @@ */ #include "globals.h" -static void handle_igm(struct io *igm_iop) +static void handle_g(struct io *g_iop) { - LIST_HEAD(head); - struct io *q_iop = dip_find_sec(igm_iop->dip, IOP_Q, igm_iop->t.sector); + struct io *q_iop = dip_find_sec(g_iop->dip, IOP_Q, g_iop->t.sector); - if (igm_iop->type == IOP_I) { - if (q_iop) - q_iop->i_time = igm_iop->t.time; - return; + iostat_getrq(g_iop); + 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 (igm_iop->type == IOP_G) - iostat_getrq(igm_iop); - else { - assert(igm_iop->type == IOP_M); - iostat_merge(igm_iop); - } +static void handle_i(struct io *i_iop) +{ + struct io *q_iop = dip_find_sec(i_iop->dip, IOP_Q, i_iop->t.sector); if (q_iop) { - update_q2i(q_iop, tdelta(q_iop->t.time, igm_iop->t.time)); - q_iop->gm_time = igm_iop->t.time; - q_iop->is_getrq = (igm_iop->type == IOP_G); + q_iop->i_time = i_iop->t.time; + if (q_iop->g_time != (__u64)-1) + update_g2i(q_iop, tdelta(q_iop->g_time, i_iop->t.time)); } } -void trace_insert(struct io *i_iop) +static void handle_m(struct io *m_iop) { - if (io_setup(i_iop, IOP_I)) - handle_igm(i_iop); + struct io *q_iop = dip_find_sec(m_iop->dip, IOP_Q, m_iop->t.sector); - io_release(i_iop); + iostat_merge(m_iop); + if (q_iop) { + q_iop->m_time = m_iop->t.time; + update_q2m(q_iop, tdelta(q_iop->t.time, m_iop->t.time)); + } } void trace_getrq(struct io *g_iop) { if (io_setup(g_iop, IOP_G)) - handle_igm(g_iop); + handle_g(g_iop); io_release(g_iop); } +void trace_insert(struct io *i_iop) +{ + if (io_setup(i_iop, IOP_I)) + handle_i(i_iop); + + io_release(i_iop); +} + void trace_merge(struct io *m_iop) { if (io_setup(m_iop, IOP_M)) - handle_igm(m_iop); + handle_m(m_iop); io_release(m_iop); } diff --git a/btt/trace_issue.c b/btt/trace_issue.c index 418afd0..f081353 100644 --- a/btt/trace_issue.c +++ b/btt/trace_issue.c @@ -39,7 +39,11 @@ static void handle_issue(struct io *d_iop) list_for_each_safe(p, q, &head) { struct io *q_iop = list_entry(p, struct io, f_head); - update_i2d(q_iop, tdelta(q_iop->gm_time, d_iop->t.time)); + if (q_iop->i_time != (__u64)-1) + update_i2d(q_iop, tdelta(q_iop->i_time, d_iop->t.time)); + else if (q_iop->m_time != (__u64)-1) + update_m2d(q_iop, tdelta(q_iop->m_time, d_iop->t.time)); + d_iop->bytes_left -= q_iop->t.bytes; LIST_DEL(&q_iop->f_head); diff --git a/btt/trace_queue.c b/btt/trace_queue.c index fe85a09..60294b6 100644 --- a/btt/trace_queue.c +++ b/btt/trace_queue.c @@ -23,15 +23,18 @@ static void handle_queue(struct io *q_iop) { seeki_add(q_iop->dip->q2q_handle, q_iop); - update_lq(&last_q, &all_avgs.q2q, q_iop->t.time); update_qregion(&all_regions, q_iop->t.time); dip_update_q(q_iop->dip, q_iop); pip_update_q(q_iop); - if (!remapper_dev(q_iop->t.device)) + if (remapper_dev(q_iop->t.device)) + update_lq(&last_q, &all_avgs.q2q_dm, q_iop->t.time); + else { update_q_histo(q_iop->t.bytes); + update_lq(&last_q, &all_avgs.q2q, q_iop->t.time); + } - q_iop->i_time = q_iop->gm_time = q_iop->d_time = (__u64)-1; - q_iop->is_getrq = -1; + q_iop->i_time = q_iop->g_time = q_iop->i_time = q_iop->m_time = + q_iop->d_time = (__u64)-1; q_iop->dip->n_qs++; q_iop->dip->t_act_q += q_iop->dip->n_act_q; |