X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=blktrace.c;h=36a7180930d0f23bf036922820a7901f165a15c9;hp=b37a54e9e1cd36ec75dffb7e9a03bfbec8e3f886;hb=19a8064ef4a2a826ee06ed061af970d1737cf840;hpb=65c42cc817949e3ad1190b333717f416e2dd4cdf diff --git a/blktrace.c b/blktrace.c index b37a54e9..36a71809 100644 --- a/blktrace.c +++ b/blktrace.c @@ -73,29 +73,29 @@ static int discard_pdu(struct thread_data *td, struct fifo *fifo, int fd, * Check if this is a blktrace binary data file. We read a single trace * into memory and check for the magic signature. */ -int is_blktrace(const char *filename, int *need_swap) +bool is_blktrace(const char *filename, int *need_swap) { struct blk_io_trace t; int fd, ret; fd = open(filename, O_RDONLY); if (fd < 0) - return 0; + return false; ret = read(fd, &t, sizeof(t)); close(fd); if (ret < 0) { perror("read blktrace"); - return 0; + return false; } else if (ret != sizeof(t)) { log_err("fio: short read on blktrace file\n"); - return 0; + return false; } if ((t.magic & 0xffffff00) == BLK_IO_TRACE_MAGIC) { *need_swap = 0; - return 1; + return true; } /* @@ -104,10 +104,10 @@ int is_blktrace(const char *filename, int *need_swap) t.magic = fio_swap32(t.magic); if ((t.magic & 0xffffff00) == BLK_IO_TRACE_MAGIC) { *need_swap = 1; - return 1; + return true; } - return 0; + return false; } #define FMINORBITS 20 @@ -273,6 +273,9 @@ static void handle_trace_discard(struct thread_data *td, unsigned int bs; int fileno; + if (td->o.replay_skip & (1u << DDIR_TRIM)) + return; + ipo = calloc(1, sizeof(*ipo)); init_ipo(ipo); fileno = trace_add_file(td, t->device, &bs); @@ -300,6 +303,11 @@ static void handle_trace_discard(struct thread_data *td, queue_io_piece(td, ipo); } +static void dump_trace(struct blk_io_trace *t) +{ + log_err("blktrace: ignoring zero byte trace: action=%x\n", t->action); +} + static void handle_trace_fs(struct thread_data *td, struct blk_io_trace *t, unsigned long long ttime, unsigned long *ios, unsigned int *rw_bs) @@ -312,13 +320,21 @@ static void handle_trace_fs(struct thread_data *td, struct blk_io_trace *t, rw = (t->action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; - /* - * Need to figure out why 0 byte writes end up here sometimes, for - * now just ignore them. - */ - if (!t->bytes) + if (rw) { + if (td->o.replay_skip & (1u << DDIR_WRITE)) + return; + } else { + if (td->o.replay_skip & (1u << DDIR_READ)) + return; + } + + if (!t->bytes) { + if (!fio_did_warn(FIO_WARN_BTRACE_ZERO)) + dump_trace(t); return; - else if (t->bytes > rw_bs[rw]) + } + + if (t->bytes > rw_bs[rw]) rw_bs[rw] = t->bytes; ios[rw]++; @@ -327,12 +343,15 @@ static void handle_trace_fs(struct thread_data *td, struct blk_io_trace *t, } static void handle_trace_flush(struct thread_data *td, struct blk_io_trace *t, - unsigned long long ttime) + unsigned long long ttime, unsigned long *ios) { struct io_piece *ipo; unsigned int bs; int fileno; + if (td->o.replay_skip & (1u << DDIR_SYNC)) + return; + ipo = calloc(1, sizeof(*ipo)); init_ipo(ipo); fileno = trace_add_file(td, t->device, &bs); @@ -341,6 +360,7 @@ static void handle_trace_flush(struct thread_data *td, struct blk_io_trace *t, ipo->ddir = DDIR_SYNC; ipo->fileno = fileno; + ios[DDIR_SYNC]++; dprint(FD_BLKTRACE, "store flush delay=%lu\n", ipo->delay); queue_io_piece(td, ipo); } @@ -381,7 +401,7 @@ static void handle_trace(struct thread_data *td, struct blk_io_trace *t, else if (t->action & BLK_TC_ACT(BLK_TC_DISCARD)) handle_trace_discard(td, t, delay, ios, bs); else if (t->action & BLK_TC_ACT(BLK_TC_FLUSH)) - handle_trace_flush(td, t, delay); + handle_trace_flush(td, t, delay, ios); else handle_trace_fs(td, t, delay, ios, bs); } @@ -401,7 +421,7 @@ static void byteswap_trace(struct blk_io_trace *t) t->pdu_len = fio_swap16(t->pdu_len); } -static int t_is_write(struct blk_io_trace *t) +static bool t_is_write(struct blk_io_trace *t) { return (t->action & BLK_TC_ACT(BLK_TC_WRITE | BLK_TC_DISCARD)) != 0; } @@ -451,20 +471,22 @@ static void depth_end(struct blk_io_trace *t, int *this_depth, int *depth) * 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. */ -int load_blktrace(struct thread_data *td, const char *filename, int need_swap) +bool load_blktrace(struct thread_data *td, const char *filename, int need_swap) { struct blk_io_trace t; - unsigned long ios[DDIR_RWDIR_CNT], skipped_writes; - unsigned int rw_bs[DDIR_RWDIR_CNT]; + unsigned long ios[DDIR_RWDIR_SYNC_CNT] = { }; + unsigned int rw_bs[DDIR_RWDIR_CNT] = { }; + unsigned long skipped_writes; struct fifo *fifo; - int fd, i, old_state; + int fd, i, old_state, max_depth; struct fio_file *f; - int this_depth[DDIR_RWDIR_CNT], depth[DDIR_RWDIR_CNT], max_depth; + int this_depth[DDIR_RWDIR_CNT] = { }; + int depth[DDIR_RWDIR_CNT] = { }; fd = open(filename, O_RDONLY); if (fd < 0) { td_verror(td, errno, "open blktrace file"); - return 1; + return false; } fifo = fifo_alloc(TRACE_FIFO_SIZE); @@ -472,14 +494,6 @@ int load_blktrace(struct thread_data *td, const char *filename, int need_swap) old_state = td_bump_runstate(td, TD_SETTING_UP); td->o.size = 0; - - for (i = 0; i < DDIR_RWDIR_CNT; i++) { - ios[i] = 0; - rw_bs[i] = 0; - this_depth[i] = 0; - depth[i] = 0; - } - skipped_writes = 0; do { int ret = trace_fifo_get(td, fifo, fd, &t, sizeof(t)); @@ -542,7 +556,7 @@ int load_blktrace(struct thread_data *td, const char *filename, int need_swap) if (!td->files_index) { log_err("fio: did not find replay device(s)\n"); - return 1; + return false; } /* @@ -562,9 +576,10 @@ int load_blktrace(struct thread_data *td, const char *filename, int need_swap) log_err("fio: %s skips replay of %lu writes due to read-only\n", td->o.name, skipped_writes); - if (!ios[DDIR_READ] && !ios[DDIR_WRITE]) { + if (!ios[DDIR_READ] && !ios[DDIR_WRITE] && !ios[DDIR_TRIM] && + !ios[DDIR_SYNC]) { log_err("fio: found no ios in blktrace data\n"); - return 1; + return false; } else if (ios[DDIR_READ] && !ios[DDIR_WRITE]) { td->o.td_ddir = TD_DDIR_READ; td->o.max_bs[DDIR_READ] = rw_bs[DDIR_READ]; @@ -592,9 +607,9 @@ int load_blktrace(struct thread_data *td, const char *filename, int need_swap) if (!fio_option_is_set(&td->o, iodepth)) td->o.iodepth = td->o.iodepth_low = max_depth; - return 0; + return true; err: close(fd); fifo_free(fifo); - return 1; + return false; }