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;
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];
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);
}
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;
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);
}
}
* 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;
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;
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)
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)
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++) {
{
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) {
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);
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;
}
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;
}
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;
case 'd':
filename = strdup(optarg);
break;
+ case 'D':
+ max_depth = atoi(optarg);
+ break;
case '?':
default:
return usage(argv);