t/btrace2fio: don't dec inflight for requeue
[fio.git] / t / btrace2fio.c
index e4e05ca4394f938f9b704bb57c51825746262c5a..04d4a28dd2ccfd8ca85496e6a17dd6724573082c 100644 (file)
@@ -19,6 +19,7 @@ static unsigned int rt_threshold = 1000000;
 static unsigned int ios_threshold = 10;
 static unsigned int rate_threshold;
 static unsigned int set_rate;
+static unsigned int max_depth = 256;
 static int output_ascii = 1;
 static char *filename;
 
@@ -45,6 +46,9 @@ struct btrace_out {
 
        int inflight;
        unsigned int depth;
+       int depth_disabled;
+       int complete_seen;
+
        uint64_t first_ttime[DDIR_RWDIR_CNT];
        uint64_t last_ttime[DDIR_RWDIR_CNT];
        uint64_t kb[DDIR_RWDIR_CNT];
@@ -125,7 +129,13 @@ static void inflight_add(struct btrace_pid *p, uint64_t sector, uint32_t len)
        i = calloc(1, sizeof(*i));
        i->p = p;
        o->inflight++;
-       o->depth = max((int) o->depth, o->inflight);
+       if (!o->depth_disabled) {
+               o->depth = max((int) o->depth, o->inflight);
+               if (o->depth >= max_depth && !o->complete_seen) {
+                       o->depth_disabled = 1;
+                       o->depth = max_depth;
+               }
+       }
        i->end_sector = sector + (len >> 9);
        __inflight_add(i);
 }
@@ -355,8 +365,6 @@ static int handle_trace(struct blk_io_trace *t, struct btrace_pid *p)
        if (act == __BLK_TA_QUEUE) {
                inflight_add(p, t->sector, t->bytes);
                ret = handle_queue_trace(t, p);
-       } else if (act == __BLK_TA_REQUEUE) {
-               p->o.inflight--;
        } else if (act == __BLK_TA_BACKMERGE) {
                struct inflight *i;
 
@@ -383,6 +391,7 @@ static int handle_trace(struct blk_io_trace *t, struct btrace_pid *p)
                i = inflight_find(t->sector + (t->bytes >> 9));
                if (i) {
                        i->p->o.kb[t_to_rwdir(t)] += (t->bytes >> 10);
+                       i->p->o.complete_seen = 1;
                        inflight_remove(i);
                }
        }
@@ -450,7 +459,7 @@ static struct btrace_pid *pid_hash_get(pid_t pid)
  * Load a blktrace file by reading all the blk_io_trace entries, and storing
  * them as io_pieces like the fio text version would do.
  */
-static int load_blktrace(const char *filename, int need_swap)
+static int load_blktrace(const char *fname, int need_swap)
 {
        struct btrace_pid *p;
        unsigned long traces;
@@ -458,7 +467,7 @@ static int load_blktrace(const char *filename, int need_swap)
        struct fifo *fifo;
        int fd, ret = 0;
 
-       fd = open(filename, O_RDONLY);
+       fd = open(fname, O_RDONLY);
        if (fd < 0) {
                perror("open trace file\n");
                return 1;
@@ -468,8 +477,7 @@ static int load_blktrace(const char *filename, int need_swap)
 
        traces = 0;
        do {
-               int ret = trace_fifo_get(fifo, fd, &t, sizeof(t));
-
+               ret = trace_fifo_get(fifo, fd, &t, sizeof(t));
                if (ret < 0)
                        goto err;
                else if (!ret)
@@ -536,11 +544,15 @@ static unsigned long o_to_kb_rate(struct btrace_out *o, int rw)
        uint64_t usec = (o->last_ttime[rw] - o->first_ttime[rw]) / 1000ULL;
        uint64_t val;
 
+       if (!usec)
+               return 0;
+
+       usec /= 1000;
        if (!usec)
                return 0;
 
        val = o->kb[rw] * 1000ULL;
-       return val / (usec / 1000ULL);
+       return val / usec;
 }
 
 static uint64_t o_first_ttime(struct btrace_out *o)
@@ -589,7 +601,7 @@ static void __output_p_ascii(struct btrace_pid *p, unsigned long *ios)
                perc = ((float) o->merges[i] * 100.0) / (float) total;
                printf("\tmerges: %lu (perc=%3.2f%%)\n", o->merges[i], perc);
                perc = ((float) o->seq[i] * 100.0) / (float) o->ios[i];
-               printf("\tseq:    %lu (perc=%3.2f%%)\n", o->seq[i], perc);
+               printf("\tseq:    %lu (perc=%3.2f%%)\n", (unsigned long) o->seq[i], perc);
                printf("\trate:   %lu KB/sec\n", o_to_kb_rate(o, i));
 
                for (j = 0; j < o->nr_bs[i]; j++) {
@@ -811,6 +823,7 @@ static int output_p(void)
 {
        unsigned long ios[DDIR_RWDIR_CNT];
        struct flist_head *e, *tmp;
+       int depth_disabled = 0;
        int ret = 0;
 
        flist_for_each_safe(e, tmp, &pid_list) {
@@ -822,8 +835,12 @@ static int output_p(void)
                        continue;
                }
                p->o.start_delay = (o_first_ttime(&p->o) / 1000ULL) - first_ttime;
+               depth_disabled += p->o.depth_disabled;
        }
 
+       if (depth_disabled)
+               log_err("fio: missing completion traces, depths capped at %u\n", max_depth);
+
        memset(ios, 0, sizeof(ios));
 
        flist_sort(NULL, &pid_list, entry_cmp);
@@ -852,6 +869,7 @@ static int usage(char *argv[])
        log_err("\t-d\tUse this file/device for replay\n");
        log_err("\t-r\tIgnore jobs with less than this KB/sec rate\n");
        log_err("\t-R\tSet rate in fio job\n");
+       log_err("\t-D\tCap queue depth at this value (def=%u)\n", max_depth);
        return 1;
 }
 
@@ -870,9 +888,11 @@ static int trace_needs_swap(const char *trace_file, int *swap)
 
        ret = read(fd, &t, sizeof(t));
        if (ret < 0) {
+               close(fd);
                perror("read");
                return 1;
        } else if (ret != sizeof(t)) {
+               close(fd);
                log_err("fio: short read on trace file\n");
                return 1;
        }
@@ -905,7 +925,7 @@ int main(int argc, char *argv[])
        if (argc < 2)
                return usage(argv);
 
-       while ((c = getopt(argc, argv, "t:n:fd:r:R")) != -1) {
+       while ((c = getopt(argc, argv, "t:n:fd:r:RD:")) != -1) {
                switch (c) {
                case 'R':
                        set_rate = 1;
@@ -925,6 +945,9 @@ int main(int argc, char *argv[])
                case 'd':
                        filename = strdup(optarg);
                        break;
+               case 'D':
+                       max_depth = atoi(optarg);
+                       break;
                case '?':
                default:
                        return usage(argv);