Handled no difference in seek times
[blktrace.git] / blkparse.c
index cdcb426803ebd603e9a958fb4944f4d1f53a2a58..517dde5841ab6f2c26edfa0890615bbd65edec6c 100644 (file)
@@ -36,7 +36,7 @@
 #include "rbtree.h"
 #include "jhash.h"
 
-static char blkparse_version[] = "0.99.2";
+static char blkparse_version[] = "0.99.3";
 
 struct skip_info {
        unsigned long start, end;
@@ -544,7 +544,7 @@ static struct process_pid_map *find_ppm(pid_t pid)
        return NULL;
 }
 
-static void add_ppm_hash(pid_t pid, const char *name)
+static struct process_pid_map *add_ppm_hash(pid_t pid, const char *name)
 {
        const int hash_idx = ppm_hash_pid(pid);
        struct process_pid_map *ppm;
@@ -558,6 +558,8 @@ static void add_ppm_hash(pid_t pid, const char *name)
                ppm->hash_next = ppm_hash_table[hash_idx];
                ppm_hash_table[hash_idx] = ppm;
        }
+
+       return ppm;
 }
 
 static void handle_notify(struct blk_io_trace *bit)
@@ -937,6 +939,8 @@ static struct io_track *find_track(struct per_dev_info *pdi, pid_t pid,
        if (!iot) {
                iot = malloc(sizeof(*iot));
                iot->ppm = find_ppm(pid);
+               if (!iot->ppm)
+                       iot->ppm = add_ppm_hash(pid, "unknown");
                iot->sector = sector;
                track_rb_insert(pdi, iot);
        }
@@ -1119,6 +1123,8 @@ static struct io_stats *find_process_io_stats(pid_t pid)
                ppi = malloc(sizeof(*ppi));
                memset(ppi, 0, sizeof(*ppi));
                ppi->ppm = find_ppm(pid);
+               if (!ppi->ppm)
+                       ppi->ppm = add_ppm_hash(pid, "unknown");
                add_ppi_to_hash(ppi);
                add_ppi_to_list(ppi);
        }
@@ -1149,10 +1155,10 @@ static inline void __account_m(struct io_stats *ios, struct blk_io_trace *t,
 {
        if (rw) {
                ios->mwrites++;
-               ios->qwrite_kb += t_kb(t);
+               ios->mwrite_kb += t_kb(t);
        } else {
                ios->mreads++;
-               ios->qread_kb += t_kb(t);
+               ios->mread_kb += t_kb(t);
        }
 }
 
@@ -1168,6 +1174,98 @@ static inline void account_m(struct blk_io_trace *t, struct per_cpu_info *pci,
        }
 }
 
+static inline void __account_pc_queue(struct io_stats *ios,
+                                     struct blk_io_trace *t, int rw)
+{
+       if (rw) {
+               ios->qwrites_pc++;
+               ios->qwrite_kb_pc += t_kb(t);
+       } else {
+               ios->qreads_pc++;
+               ios->qread_kb += t_kb(t);
+       }
+}
+
+static inline void account_pc_queue(struct blk_io_trace *t,
+                                   struct per_cpu_info *pci, int rw)
+{
+       __account_pc_queue(&pci->io_stats, t, rw);
+
+       if (per_process_stats) {
+               struct io_stats *ios = find_process_io_stats(t->pid);
+
+               __account_pc_queue(ios, t, rw);
+       }
+}
+
+static inline void __account_pc_issue(struct io_stats *ios, int rw,
+                                     unsigned int bytes)
+{
+       if (rw) {
+               ios->iwrites_pc++;
+               ios->iwrite_kb_pc += bytes >> 10;
+       } else {
+               ios->ireads_pc++;
+               ios->iread_kb_pc += bytes >> 10;
+       }
+}
+
+static inline void account_pc_issue(struct blk_io_trace *t,
+                                   struct per_cpu_info *pci, int rw)
+{
+       __account_pc_issue(&pci->io_stats, rw, t->bytes);
+
+       if (per_process_stats) {
+               struct io_stats *ios = find_process_io_stats(t->pid);
+
+               __account_pc_issue(ios, rw, t->bytes);
+       }
+}
+
+static inline void __account_pc_requeue(struct io_stats *ios,
+                                       struct blk_io_trace *t, int rw)
+{
+       if (rw) {
+               ios->wrqueue_pc++;
+               ios->iwrite_kb_pc -= t_kb(t);
+       } else {
+               ios->rrqueue_pc++;
+               ios->iread_kb_pc -= t_kb(t);
+       }
+}
+
+static inline void account_pc_requeue(struct blk_io_trace *t,
+                                     struct per_cpu_info *pci, int rw)
+{
+       __account_pc_requeue(&pci->io_stats, t, rw);
+
+       if (per_process_stats) {
+               struct io_stats *ios = find_process_io_stats(t->pid);
+
+               __account_pc_requeue(ios, t, rw);
+       }
+}
+
+static inline void __account_pc_c(struct io_stats *ios, int rw)
+{
+       if (rw)
+               ios->cwrites_pc++;
+       else
+               ios->creads_pc++;
+}
+
+static inline void account_pc_c(struct blk_io_trace *t,
+                               struct per_cpu_info *pci, int rw)
+{
+       __account_pc_c(&pci->io_stats, rw);
+
+       if (per_process_stats) {
+               struct io_stats *ios = find_process_io_stats(t->pid);
+
+               __account_pc_c(ios, rw);
+       }
+}
+
 static inline void __account_queue(struct io_stats *ios, struct blk_io_trace *t,
                                   int rw)
 {
@@ -1347,13 +1445,16 @@ static void log_pc(struct per_cpu_info *pci, struct blk_io_trace *t, char *act)
        process_fmt(act, pci, t, -1ULL, t->pdu_len, buf);
 }
 
-static void dump_trace_pc(struct blk_io_trace *t, struct per_cpu_info *pci)
+static void dump_trace_pc(struct blk_io_trace *t, struct per_dev_info *pdi,
+                         struct per_cpu_info *pci)
 {
+       int w = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0;
        int act = t->action & 0xffff;
 
        switch (act) {
                case __BLK_TA_QUEUE:
                        log_generic(pci, t, "Q");
+                       account_pc_queue(t, pci, w);
                        break;
                case __BLK_TA_GETRQ:
                        log_generic(pci, t, "G");
@@ -1362,13 +1463,27 @@ static void dump_trace_pc(struct blk_io_trace *t, struct per_cpu_info *pci)
                        log_generic(pci, t, "S");
                        break;
                case __BLK_TA_REQUEUE:
+                       /*
+                        * can happen if we miss traces, don't let it go
+                        * below zero
+                        */
+                       if (pdi->cur_depth[w])
+                               pdi->cur_depth[w]--;
+                       account_pc_requeue(t, pci, w);
                        log_generic(pci, t, "R");
                        break;
                case __BLK_TA_ISSUE:
+                       account_pc_issue(t, pci, w);
+                       pdi->cur_depth[w]++;
+                       if (pdi->cur_depth[w] > pdi->max_depth[w])
+                               pdi->max_depth[w] = pdi->cur_depth[w];
                        log_pc(pci, t, "D");
                        break;
                case __BLK_TA_COMPLETE:
+                       if (pdi->cur_depth[w])
+                               pdi->cur_depth[w]--;
                        log_pc(pci, t, "C");
+                       account_pc_c(t, pci, w);
                        break;
                case __BLK_TA_INSERT:
                        log_pc(pci, t, "I");
@@ -1463,7 +1578,7 @@ static void dump_trace(struct blk_io_trace *t, struct per_cpu_info *pci,
 {
        if (text_output) {
                if (t->action & BLK_TC_ACT(BLK_TC_PC))
-                       dump_trace_pc(t, pci);
+                       dump_trace_pc(t, pdi, pci);
                else
                        dump_trace_fs(t, pdi, pci);
        }
@@ -1506,19 +1621,29 @@ static void dump_io_stats(struct per_dev_info *pdi, struct io_stats *ios,
 
        fprintf(ofp, " Reads Queued:    %s, %siB\t", size_cnv(x, ios->qreads, 0), size_cnv(y, ios->qread_kb, 1));
        fprintf(ofp, " Writes Queued:    %s, %siB\n", size_cnv(x, ios->qwrites, 0), size_cnv(y, ios->qwrite_kb, 1));
-
        fprintf(ofp, " Read Dispatches: %s, %siB\t", size_cnv(x, ios->ireads, 0), size_cnv(y, ios->iread_kb, 1));
        fprintf(ofp, " Write Dispatches: %s, %siB\n", size_cnv(x, ios->iwrites, 0), size_cnv(y, ios->iwrite_kb, 1));
        fprintf(ofp, " Reads Requeued:  %s\t\t", size_cnv(x, ios->rrqueue, 0));
        fprintf(ofp, " Writes Requeued:  %s\n", size_cnv(x, ios->wrqueue, 0));
        fprintf(ofp, " Reads Completed: %s, %siB\t", size_cnv(x, ios->creads, 0), size_cnv(y, ios->cread_kb, 1));
        fprintf(ofp, " Writes Completed: %s, %siB\n", size_cnv(x, ios->cwrites, 0), size_cnv(y, ios->cwrite_kb, 1));
-       fprintf(ofp, " Read Merges:     %'8lu%8c\t", ios->mreads, ' ');
-       fprintf(ofp, " Write Merges:     %'8lu\n", ios->mwrites);
+       fprintf(ofp, " Read Merges:     %s, %siB\t", size_cnv(x, ios->mreads, 0), size_cnv(y, ios->mread_kb, 1));
+       fprintf(ofp, " Write Merges:     %s, %siB\n", size_cnv(x, ios->mwrites, 0), size_cnv(y, ios->mwrite_kb, 1));
        if (pdi) {
                fprintf(ofp, " Read depth:      %'8u%8c\t", pdi->max_depth[0], ' ');
                fprintf(ofp, " Write depth:      %'8u\n", pdi->max_depth[1]);
        }
+       if (ios->qreads_pc || ios->qwrites_pc || ios->ireads_pc || ios->iwrites_pc ||
+           ios->rrqueue_pc || ios->wrqueue_pc || ios->creads_pc || ios->cwrites_pc) {
+               fprintf(ofp, " PC Reads Queued: %s, %siB\t", size_cnv(x, ios->qreads_pc, 0), size_cnv(y, ios->qread_kb_pc, 1));
+               fprintf(ofp, " PC Writes Queued: %s, %siB\n", size_cnv(x, ios->qwrites_pc, 0), size_cnv(y, ios->qwrite_kb_pc, 1));
+               fprintf(ofp, " PC Read Disp.:   %s, %siB\t", size_cnv(x, ios->ireads_pc, 0), size_cnv(y, ios->iread_kb_pc, 1));
+               fprintf(ofp, " PC Write Disp.:   %s, %siB\n", size_cnv(x, ios->iwrites_pc, 0), size_cnv(y, ios->iwrite_kb_pc, 1));
+               fprintf(ofp, " PC Reads Req.:   %s\t\t", size_cnv(x, ios->rrqueue_pc, 0));
+               fprintf(ofp, " PC Writes Req.:   %s\n", size_cnv(x, ios->wrqueue_pc, 0));
+               fprintf(ofp, " PC Reads Compl.: %s\t\t", size_cnv(x, ios->creads_pc, 0));
+               fprintf(ofp, " PC Writes Compl.: %s\n", size_cnv(x, ios->cwrites, 0));
+       }
        fprintf(ofp, " IO unplugs:      %'8lu%8c\t", ios->io_unplugs, ' ');
        fprintf(ofp, " Timer unplugs:    %'8lu\n", ios->timer_unplugs);
 }
@@ -1646,6 +1771,22 @@ static void show_device_and_cpu_stats(void)
                        total.cwrite_kb += ios->cwrite_kb;
                        total.iread_kb += ios->iread_kb;
                        total.iwrite_kb += ios->iwrite_kb;
+                       total.mread_kb += ios->mread_kb;
+                       total.mwrite_kb += ios->mwrite_kb;
+
+                       total.qreads_pc += ios->qreads_pc;
+                       total.qwrites_pc += ios->qwrites_pc;
+                       total.creads_pc += ios->creads_pc;
+                       total.cwrites_pc += ios->cwrites_pc;
+                       total.ireads_pc += ios->ireads_pc;
+                       total.iwrites_pc += ios->iwrites_pc;
+                       total.rrqueue_pc += ios->rrqueue_pc;
+                       total.wrqueue_pc += ios->wrqueue_pc;
+                       total.qread_kb_pc += ios->qread_kb_pc;
+                       total.qwrite_kb_pc += ios->qwrite_kb_pc;
+                       total.iread_kb_pc += ios->iread_kb_pc;
+                       total.iwrite_kb_pc += ios->iwrite_kb_pc;
+
                        total.timer_unplugs += ios->timer_unplugs;
                        total.io_unplugs += ios->io_unplugs;
 
@@ -2283,17 +2424,19 @@ static int handle(struct ms_stream *msp)
        struct blk_io_trace *bit;
 
        t = ms_peek(msp);
-       if (t->bit->time > stopwatch_end)
-               return 0;
 
        bit = t->bit;
        pdi = msp->pdi;
        pci = get_cpu_info(pdi, msp->cpu);
        pci->nelems++;
-
        bit->time -= genesis_time;
+
+       if (t->bit->time > stopwatch_end)
+               return 0;
+
        pdi->last_reported_time = bit->time;
-       if (bit->action & (act_mask << BLK_TC_SHIFT))
+       if ((bit->action & (act_mask << BLK_TC_SHIFT))&&
+           t->bit->time >= stopwatch_start)
                dump_trace(bit, pci, pdi);
 
        ms_deq(msp);
@@ -2612,7 +2755,7 @@ int main(int argc, char *argv[])
        while (optind < argc) {
                if (is_pipe(argv[optind]) && !pipeline) {
                        pipeline = 1;
-                       pipename = strdup(optarg);
+                       pipename = strdup(argv[optind]);
                } else if (resize_devices(argv[optind]) != 0)
                        return 1;
                optind++;