Separated out g/i/m trace handling.
authorAlan D. Brunelle <Alan.Brunelle@hp.com>
Mon, 10 Dec 2007 18:41:37 +0000 (13:41 -0500)
committerAlan D. Brunelle <Alan.Brunelle@hp.com>
Mon, 10 Dec 2007 18:41:37 +0000 (13:41 -0500)
Also separated out DM-device calculations.

btt/bt_timeline.c
btt/doc/btt.tex
btt/globals.h
btt/inlines.h
btt/iostat.c
btt/output.c
btt/proc.c
btt/trace_complete.c
btt/trace_im.c
btt/trace_issue.c
btt/trace_queue.c

index f67c2adb3c617ea1ee7b2e56885ad7c1ef8a366d..b1f480aaef62386912f11f4d61250d8e6c5dc0b7 100644 (file)
@@ -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;
index 3d3abd2921af98d0c08d12556429cba8c3ecbc70..0fe44eff5a2d142979640b537ae6b360c5fc4f81 100644 (file)
@@ -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> ]
index 4e8edc6597d7b507fb322d03f3fe01dbdc1753d3..4176fb41b8a3236aaaa97cb0d969d2bbf8957181 100644 (file)
@@ -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)
index 43dada09e41ef917e3c0270ec9eeb36b7eb51e57..875b75b2f70a4f2e69c9b55f7711c44b61740c48 100644 (file)
  *
  */
 
+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(&reg->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;
index 785029dab52c984dbe56d8c0e7481fe2f4cd4c71..f46d57215908e6080c0f9fde2fc3fd84734af811 100644 (file)
@@ -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));
 }
index 787de7069773f8dd40a077bcb4a843af3803e1d7..33a9a738e78fd3fc4e75144cec9f36e6668e4e3c 100644 (file)
 #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);
 
index 07563205aed98b182f1e5de6fb561c55105efa93..5818db469799e2c0e92a93f7ade67a4627f46f65 100644 (file)
@@ -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);
        }
 }
index c51d43dd81cb9612accfbcee363c8c9b7e282a18..b4dcadddea03150cf74010babf27622aad49c642 100644 (file)
@@ -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;
index f97c59bce713b2940889263022daee6ba77865ca..c30b4ec50f3bfa0945ea99f961068661f1b18199 100644 (file)
  */
 #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);
 }
index 418afd0f1d87fbe60d09d170118d6d605e52018d..f08135388017636d02d68e94c7cdc84385f98232 100644 (file)
@@ -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);
 
index fe85a095dc44fc9bb2672be9377bdace4f6d0c58..60294b6e52b769963536790350e226853a9c1d27 100644 (file)
 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;