X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=iolog.c;h=a8bead11292c824eb3371f4f2c3e7a8545108cf7;hb=cb7e0ace739cbd5ca8a434a40fef4de469d59a5e;hp=1eb89b29171c2796ce0df8743cdb40b866a1b5e6;hpb=12d02717a293cdd0c85504c958f7bf57411bb30b;p=fio.git diff --git a/iolog.c b/iolog.c index 1eb89b29..a8bead11 100644 --- a/iolog.c +++ b/iolog.c @@ -58,6 +58,7 @@ void log_file(struct thread_data *td, struct fio_file *f, static void iolog_delay(struct thread_data *td, unsigned long delay) { unsigned long usec = utime_since_now(&td->last_issue); + unsigned long this_delay; if (delay < usec) return; @@ -70,7 +71,14 @@ static void iolog_delay(struct thread_data *td, unsigned long delay) if (delay < 100) return; - usec_sleep(td, delay); + while (delay && !td->terminate) { + this_delay = delay; + if (this_delay > 500000) + this_delay = 500000; + + usec_sleep(td, this_delay); + delay -= this_delay; + } } static int ipo_special(struct thread_data *td, struct io_piece *ipo) @@ -260,6 +268,33 @@ restart: td->io_hist_len++; } +void unlog_io_piece(struct thread_data *td, struct io_u *io_u) +{ + struct io_piece *ipo = io_u->ipo; + + if (!ipo) + return; + + if (ipo->flags & IP_F_ONRB) + rb_erase(&ipo->rb_node, &td->io_hist_tree); + else if (ipo->flags & IP_F_ONLIST) + flist_del(&ipo->list); + + free(ipo); + io_u->ipo = NULL; + td->io_hist_len--; +} + +void trim_io_piece(struct thread_data *td, struct io_u *io_u) +{ + struct io_piece *ipo = io_u->ipo; + + if (!ipo) + return; + + ipo->len = io_u->xfer_buflen - io_u->resid; +} + void write_iolog_close(struct thread_data *td) { fflush(td->iolog_f); @@ -375,6 +410,7 @@ static int read_iolog2(struct thread_data *td, FILE *f) td->o.max_bs[rw] = bytes; ipo->fileno = fileno; ipo->file_action = file_action; + td->o.size += bytes; } queue_io_piece(td, ipo); @@ -503,7 +539,8 @@ int init_iolog(struct thread_data *td) return ret; } -void setup_log(struct io_log **log, unsigned long avg_msec, int log_type) +void setup_log(struct io_log **log, unsigned long avg_msec, int log_type, + int log_offset, const char *filename) { struct io_log *l = malloc(sizeof(*l)); @@ -511,8 +548,10 @@ void setup_log(struct io_log **log, unsigned long avg_msec, int log_type) l->nr_samples = 0; l->max_samples = 1024; l->log_type = log_type; - l->log = malloc(l->max_samples * sizeof(struct io_sample)); + l->log_offset = log_offset; + l->log = malloc(l->max_samples * log_entry_sz(l)); l->avg_msec = avg_msec; + l->filename = strdup(filename); *log = l; } @@ -542,13 +581,20 @@ static void clear_file_buffer(void *buf) } #endif -void __finish_log(struct io_log *log, const char *name) +static void free_log(struct io_log *log) { - unsigned int i; + free(log->log); + free(log->filename); + free(log); +} + +void __finish_log(struct io_log *log) +{ + uint64_t i; void *buf; FILE *f; - f = fopen(name, "a"); + f = fopen(log->filename, "a"); if (!f) { perror("fopen log"); return; @@ -557,98 +603,95 @@ void __finish_log(struct io_log *log, const char *name) buf = set_file_buffer(f); for (i = 0; i < log->nr_samples; i++) { - fprintf(f, "%lu, %lu, %u, %u\n", - (unsigned long) log->log[i].time, - (unsigned long) log->log[i].val, - log->log[i].ddir, log->log[i].bs); + struct io_sample *s = get_sample(log, i); + + if (!log->log_offset) { + fprintf(f, "%lu, %lu, %u, %u\n", + (unsigned long) s->time, + (unsigned long) s->val, + s->ddir, s->bs); + } else { + struct io_sample_offset *so = (void *) s; + + fprintf(f, "%lu, %lu, %u, %u, %llu\n", + (unsigned long) s->time, + (unsigned long) s->val, + s->ddir, s->bs, + (unsigned long long) so->offset); + } } fclose(f); clear_file_buffer(buf); - free(log->log); - free(log); + free_log(log); } -static int finish_log_named(struct thread_data *td, struct io_log *log, - const char *prefix, const char *postfix, - int trylock) +static int finish_log(struct thread_data *td, struct io_log *log, int trylock) { - char file_name[256]; - - snprintf(file_name, sizeof(file_name), "%s_%s.log", prefix, postfix); - if (trylock) { - if (fio_trylock_file(file_name)) + if (fio_trylock_file(log->filename)) return 1; } else - fio_lock_file(file_name); + fio_lock_file(log->filename); if (td->client_type == FIO_CLIENT_TYPE_GUI) { - fio_send_iolog(td, log, file_name); - free(log->log); - free(log); + fio_send_iolog(td, log, log->filename); + free_log(log); } else - __finish_log(log, file_name); + __finish_log(log); - fio_unlock_file(file_name); + fio_unlock_file(log->filename); return 0; } -static int finish_log(struct thread_data *td, struct io_log *log, - const char *name, int trylock) -{ - return finish_log_named(td, log, td->o.name, name, trylock); -} - -static int write_this_log(struct thread_data *td, struct io_log *log, - const char *log_file, const char *name, int try) +static int write_iops_log(struct thread_data *td, int try) { - int ret; + struct io_log *log = td->iops_log; if (!log) return 0; - if (log_file) - ret = finish_log_named(td, log, log_file, name, try); - else - ret = finish_log(td, log, name, try); - - return ret; -} - -static int write_iops_log(struct thread_data *td, int try) -{ - struct thread_options *o = &td->o; - - return write_this_log(td, td->iops_log, o->iops_log_file, "iops", try); + return finish_log(td, log, try); } static int write_slat_log(struct thread_data *td, int try) { - struct thread_options *o = &td->o; + struct io_log *log = td->slat_log; + + if (!log) + return 0; - return write_this_log(td, td->slat_log, o->lat_log_file, "slat", try); + return finish_log(td, log, try); } static int write_clat_log(struct thread_data *td, int try) { - struct thread_options *o = &td->o; + struct io_log *log = td->clat_log; + + if (!log) + return 0; - return write_this_log(td, td->clat_log, o->lat_log_file, "clat" , try); + return finish_log(td, log, try); } static int write_lat_log(struct thread_data *td, int try) { - struct thread_options *o = &td->o; + struct io_log *log = td->lat_log; - return write_this_log(td, td->lat_log, o->lat_log_file, "lat", try); + if (!log) + return 0; + + return finish_log(td, log, try); } static int write_bandw_log(struct thread_data *td, int try) { - struct thread_options *o = &td->o; + struct io_log *log = td->bw_log; + + if (!log) + return 0; - return write_this_log(td, td->bw_log, o->bw_log_file, "bw", try); + return finish_log(td, log, try); } enum {