X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=iolog.c;h=b72dcf9791cfa242ceace8b4080a03934e9fa554;hp=aa9c3bb1e4eca43fa0cf1c9794df39656ba80972;hb=HEAD;hpb=a7c386edc19f3ef121b037b60b02852ffbcd6d65 diff --git a/iolog.c b/iolog.c index aa9c3bb1..96af4f33 100644 --- a/iolog.c +++ b/iolog.c @@ -82,8 +82,8 @@ static void iolog_delay(struct thread_data *td, unsigned long delay) { uint64_t usec = utime_since_now(&td->last_issue); unsigned long orig_delay = delay; - uint64_t this_delay; struct timespec ts; + int ret = 0; if (delay < td->time_offset) { td->time_offset = 0; @@ -97,13 +97,15 @@ static void iolog_delay(struct thread_data *td, unsigned long delay) delay -= usec; fio_gettime(&ts, NULL); - while (delay && !td->terminate) { - this_delay = delay; - if (this_delay > 500000) - this_delay = 500000; - usec_sleep(td, this_delay); - delay -= this_delay; + while (delay && !td->terminate) { + ret = io_u_queued_complete(td, 0); + if (ret < 0) + td_verror(td, -ret, "io_u_queued_complete"); + if (td->flags & TD_F_REGROW_LOGS) + regrow_logs(td); + if (utime_since_now(&ts) > delay) + break; } usec = utime_since_now(&ts); @@ -439,7 +441,7 @@ static bool read_iolog(struct thread_data *td) unsigned long long offset; unsigned int bytes; unsigned long long delay = 0; - int reads, writes, waits, fileno = 0, file_action = 0; /* stupid gcc */ + int reads, writes, trims, waits, fileno = 0, file_action = 0; /* stupid gcc */ char *rfname, *fname, *act; char *str, *p; enum fio_ddir rw; @@ -461,7 +463,7 @@ static bool read_iolog(struct thread_data *td) rfname = fname = malloc(256+16); act = malloc(256+16); - syncs = reads = writes = waits = 0; + syncs = reads = writes = trims = waits = 0; while ((p = fgets(str, 4096, td->io_log_rfile)) != NULL) { struct io_piece *ipo; int r; @@ -492,17 +494,25 @@ static bool read_iolog(struct thread_data *td) */ if (!strcmp(act, "wait")) rw = DDIR_WAIT; - else if (!strcmp(act, "read")) + else if (!strcmp(act, "read")) { + if (td->o.replay_skip & (1u << DDIR_READ)) + continue; rw = DDIR_READ; - else if (!strcmp(act, "write")) + } else if (!strcmp(act, "write")) { + if (td->o.replay_skip & (1u << DDIR_WRITE)) + continue; rw = DDIR_WRITE; - else if (!strcmp(act, "sync")) + } else if (!strcmp(act, "sync")) { + if (td->o.replay_skip & (1u << DDIR_SYNC)) + continue; rw = DDIR_SYNC; - else if (!strcmp(act, "datasync")) + } else if (!strcmp(act, "datasync")) rw = DDIR_DATASYNC; - else if (!strcmp(act, "trim")) + else if (!strcmp(act, "trim")) { + if (td->o.replay_skip & (1u << DDIR_TRIM)) + continue; rw = DDIR_TRIM; - else { + } else { log_err("fio: bad iolog file action: %s\n", act); continue; @@ -544,6 +554,13 @@ static bool read_iolog(struct thread_data *td) if (read_only) continue; writes++; + } else if (rw == DDIR_TRIM) { + /* + * Don't add a trim for ro mode + */ + if (read_only) + continue; + trims++; } else if (rw == DDIR_WAIT) { if (td->o.no_stall) continue; @@ -620,19 +637,22 @@ static bool read_iolog(struct thread_data *td) { io_u_quiesce(td); free_io_mem(td); - init_io_u_buffers(td); + if (init_io_u_buffers(td)) + return false; } return true; } - if (!reads && !writes && !waits) + if (!reads && !writes && !waits && !trims) return false; - else if (reads && !writes) - td->o.td_ddir = TD_DDIR_READ; - else if (!reads && writes) - td->o.td_ddir = TD_DDIR_WRITE; - else - td->o.td_ddir = TD_DDIR_RW; + + td->o.td_ddir = 0; + if (reads) + td->o.td_ddir |= TD_DDIR_READ; + if (writes) + td->o.td_ddir |= TD_DDIR_WRITE; + if (trims) + td->o.td_ddir |= TD_DDIR_TRIM; return true; } @@ -794,6 +814,8 @@ bool init_iolog(struct thread_data *td) if (!ret) td_verror(td, EINVAL, "failed initializing iolog"); + init_disk_util(td); + return ret; } @@ -844,6 +866,13 @@ void setup_log(struct io_log **log, struct log_params *p, l->log_ddir_mask = LOG_OFFSET_SAMPLE_BIT; if (l->log_prio) l->log_ddir_mask |= LOG_PRIO_SAMPLE_BIT; + /* + * The bandwidth-log option generates agg-read_bw.log, + * agg-write_bw.log and agg-trim_bw.log for which l->td is NULL. + * Check if l->td is valid before dereferencing it. + */ + if (l->td && l->td->o.log_max == IO_LOG_SAMPLE_BOTH) + l->log_ddir_mask |= LOG_AVG_MAX_SAMPLE_BIT; INIT_FLIST_HEAD(&l->chunk_list); @@ -970,7 +999,7 @@ static void flush_hist_samples(FILE *f, int hist_coarseness, void *samples, void flush_samples(FILE *f, void *samples, uint64_t sample_size) { struct io_sample *s; - int log_offset, log_prio; + int log_offset, log_prio, log_avg_max; uint64_t i, nr_samples; unsigned int prio_val; const char *fmt; @@ -981,17 +1010,32 @@ void flush_samples(FILE *f, void *samples, uint64_t sample_size) s = __get_sample(samples, 0, 0); log_offset = (s->__ddir & LOG_OFFSET_SAMPLE_BIT) != 0; log_prio = (s->__ddir & LOG_PRIO_SAMPLE_BIT) != 0; + log_avg_max = (s->__ddir & LOG_AVG_MAX_SAMPLE_BIT) != 0; if (log_offset) { - if (log_prio) - fmt = "%lu, %" PRId64 ", %u, %llu, %llu, 0x%04x\n"; - else - fmt = "%lu, %" PRId64 ", %u, %llu, %llu, %u\n"; + if (log_prio) { + if (log_avg_max) + fmt = "%" PRIu64 ", %" PRId64 ", %" PRId64 ", %u, %llu, %llu, 0x%04x\n"; + else + fmt = "%" PRIu64 ", %" PRId64 ", %u, %llu, %llu, 0x%04x\n"; + } else { + if (log_avg_max) + fmt = "%" PRIu64 ", %" PRId64 ", %" PRId64 ", %u, %llu, %llu, %u\n"; + else + fmt = "%" PRIu64 ", %" PRId64 ", %u, %llu, %llu, %u\n"; + } } else { - if (log_prio) - fmt = "%lu, %" PRId64 ", %u, %llu, 0x%04x\n"; - else - fmt = "%lu, %" PRId64 ", %u, %llu, %u\n"; + if (log_prio) { + if (log_avg_max) + fmt = "%" PRIu64 ", %" PRId64 ", %" PRId64 ", %u, %llu, 0x%04x\n"; + else + fmt = "%" PRIu64 ", %" PRId64 ", %u, %llu, 0x%04x\n"; + } else { + if (log_avg_max) + fmt = "%" PRIu64 ", %" PRId64 ", %" PRId64 ", %u, %llu, %u\n"; + else + fmt = "%" PRIu64 ", %" PRId64 ", %u, %llu, %u\n"; + } } nr_samples = sample_size / __log_entry_sz(log_offset); @@ -1005,20 +1049,37 @@ void flush_samples(FILE *f, void *samples, uint64_t sample_size) prio_val = ioprio_value_is_class_rt(s->priority); if (!log_offset) { - fprintf(f, fmt, - (unsigned long) s->time, - s->data.val, - io_sample_ddir(s), (unsigned long long) s->bs, - prio_val); + if (log_avg_max) + fprintf(f, fmt, + s->time, + s->data.val.val0, + s->data.val.val1, + io_sample_ddir(s), (unsigned long long) s->bs, + prio_val); + else + fprintf(f, fmt, + s->time, + s->data.val.val0, + io_sample_ddir(s), (unsigned long long) s->bs, + prio_val); } else { struct io_sample_offset *so = (void *) s; - fprintf(f, fmt, - (unsigned long) s->time, - s->data.val, - io_sample_ddir(s), (unsigned long long) s->bs, - (unsigned long long) so->offset, - prio_val); + if (log_avg_max) + fprintf(f, fmt, + s->time, + s->data.val.val0, + s->data.val.val1, + io_sample_ddir(s), (unsigned long long) s->bs, + (unsigned long long) so->offset, + prio_val); + else + fprintf(f, fmt, + s->time, + s->data.val.val0, + io_sample_ddir(s), (unsigned long long) s->bs, + (unsigned long long) so->offset, + prio_val); } } } @@ -1857,9 +1918,7 @@ void td_writeout_logs(struct thread_data *td, bool unit_logs) void fio_writeout_logs(bool unit_logs) { - struct thread_data *td; - int i; - - for_each_td(td, i) + for_each_td(td) { td_writeout_logs(td, unit_logs); + } end_for_each(); }