X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=stat.c;h=7a35117a6f1998faae15cae2c1e3b660205470b7;hp=704947f548950a3076651b54087ff6653b73a198;hb=99955d3d3e290ccb06583a821a8112210e4b332d;hpb=f03189f8089d91502737be404ca06bdb48fa3887 diff --git a/stat.c b/stat.c index 704947f5..7a35117a 100644 --- a/stat.c +++ b/stat.c @@ -16,6 +16,9 @@ #include "lib/pow2.h" #include "lib/output_buffer.h" #include "helper_thread.h" +#include "smalloc.h" + +#define LOG_MSEC_SLACK 10 struct fio_mutex *stat_mutex; @@ -1877,7 +1880,7 @@ static struct io_logs *get_new_log(struct io_log *iolog) new_size = new_samples * log_entry_sz(iolog); - cur_log = malloc(sizeof(*cur_log)); + cur_log = smalloc(sizeof(*cur_log)); if (cur_log) { INIT_FLIST_HEAD(&cur_log->list); cur_log->log = malloc(new_size); @@ -1888,7 +1891,7 @@ static struct io_logs *get_new_log(struct io_log *iolog) iolog->cur_log_max = new_samples; return cur_log; } - free(cur_log); + sfree(cur_log); } return NULL; @@ -1948,6 +1951,7 @@ static struct io_logs *regrow_log(struct io_log *iolog) dst = get_sample(iolog, cur_log, i); memcpy(dst, src, log_entry_sz(iolog)); } + cur_log->nr_samples = iolog->pending->nr_samples; iolog->pending->nr_samples = 0; return cur_log; @@ -1982,11 +1986,14 @@ static struct io_logs *get_cur_log(struct io_log *iolog) return cur_log; /* - * Out of space. If we're in IO offload mode, add a new log chunk - * inline. If we're doing inline submissions, flag 'td' as needing - * a log regrow and we'll take care of it on the submission side. + * Out of space. If we're in IO offload mode, or we're not doing + * per unit logging (hence logging happens outside of the IO thread + * as well), add a new log chunk inline. If we're doing inline + * submissions, flag 'td' as needing a log regrow and we'll take + * care of it on the submission side. */ - if (iolog->td->o.io_submit_mode == IO_MODE_OFFLOAD) + if (iolog->td->o.io_submit_mode == IO_MODE_OFFLOAD || + !per_unit_log(iolog)) return regrow_log(iolog); iolog->td->flags |= TD_F_REGROW_LOGS; @@ -2102,14 +2109,14 @@ static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed, __add_stat_to_log(iolog, ddir, elapsed, log_max); } -static void add_log_sample(struct thread_data *td, struct io_log *iolog, +static long add_log_sample(struct thread_data *td, struct io_log *iolog, unsigned long val, enum fio_ddir ddir, unsigned int bs, uint64_t offset) { unsigned long elapsed, this_window; if (!ddir_rw(ddir)) - return; + return 0; elapsed = mtime_since_now(&td->epoch); @@ -2118,7 +2125,7 @@ static void add_log_sample(struct thread_data *td, struct io_log *iolog, */ if (!iolog->avg_msec) { __add_log_sample(iolog, val, ddir, bs, elapsed, offset); - return; + return 0; } /* @@ -2132,12 +2139,17 @@ static void add_log_sample(struct thread_data *td, struct io_log *iolog, * need to do. */ this_window = elapsed - iolog->avg_last; - if (this_window < iolog->avg_msec) - return; + if (this_window < iolog->avg_msec) { + int diff = iolog->avg_msec - this_window; + + if (inline_log(iolog) || diff > LOG_MSEC_SLACK) + return diff; + } _add_stat_to_log(iolog, elapsed, td->o.log_max != 0); - iolog->avg_last = elapsed; + iolog->avg_last = elapsed - (this_window - iolog->avg_msec); + return iolog->avg_msec; } void finalize_logs(struct thread_data *td, bool unit_logs) @@ -2259,10 +2271,13 @@ static int add_bw_samples(struct thread_data *td, struct timeval *t) struct thread_stat *ts = &td->ts; unsigned long spent, rate; enum fio_ddir ddir; + unsigned int next, next_log; + + next_log = td->o.bw_avg_time; spent = mtime_since(&td->bw_sample_time, t); if (spent < td->o.bw_avg_time && - td->o.bw_avg_time - spent >= 10) + td->o.bw_avg_time - spent >= LOG_MSEC_SLACK) return td->o.bw_avg_time - spent; td_io_u_lock(td); @@ -2290,7 +2305,8 @@ static int add_bw_samples(struct thread_data *td, struct timeval *t) if (td->o.min_bs[ddir] == td->o.max_bs[ddir]) bs = td->o.min_bs[ddir]; - add_log_sample(td, td->bw_log, rate, ddir, bs, 0); + next = add_log_sample(td, td->bw_log, rate, ddir, bs, 0); + next_log = min(next_log, next); } td->stat_io_bytes[ddir] = td->this_io_bytes[ddir]; @@ -2301,9 +2317,10 @@ static int add_bw_samples(struct thread_data *td, struct timeval *t) td_io_u_unlock(td); if (spent <= td->o.bw_avg_time) - return td->o.bw_avg_time; + return min(next_log, td->o.bw_avg_time); - return td->o.bw_avg_time - (1 + spent - td->o.bw_avg_time); + next = td->o.bw_avg_time - (1 + spent - td->o.bw_avg_time); + return min(next, next_log); } void add_iops_sample(struct thread_data *td, struct io_u *io_u, @@ -2327,10 +2344,13 @@ static int add_iops_samples(struct thread_data *td, struct timeval *t) struct thread_stat *ts = &td->ts; unsigned long spent, iops; enum fio_ddir ddir; + unsigned int next, next_log; + + next_log = td->o.iops_avg_time; spent = mtime_since(&td->iops_sample_time, t); if (spent < td->o.iops_avg_time && - td->o.iops_avg_time - spent >= 10) + td->o.iops_avg_time - spent >= LOG_MSEC_SLACK) return td->o.iops_avg_time - spent; td_io_u_lock(td); @@ -2358,7 +2378,8 @@ static int add_iops_samples(struct thread_data *td, struct timeval *t) if (td->o.min_bs[ddir] == td->o.max_bs[ddir]) bs = td->o.min_bs[ddir]; - add_log_sample(td, td->iops_log, iops, ddir, bs, 0); + next = add_log_sample(td, td->iops_log, iops, ddir, bs, 0); + next_log = min(next_log, next); } td->stat_io_blocks[ddir] = td->this_io_blocks[ddir]; @@ -2369,9 +2390,10 @@ static int add_iops_samples(struct thread_data *td, struct timeval *t) td_io_u_unlock(td); if (spent <= td->o.iops_avg_time) - return td->o.iops_avg_time; + return min(next_log, td->o.iops_avg_time); - return td->o.iops_avg_time - (1 + spent - td->o.iops_avg_time); + next = td->o.iops_avg_time - (1 + spent - td->o.iops_avg_time); + return min(next, next_log); } /* @@ -2387,7 +2409,7 @@ int calc_log_samples(void) fio_gettime(&now, NULL); for_each_td(td, i) { - if (!in_ramp_time(td) || + if (in_ramp_time(td) || !(td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING)) { next = min(td->o.iops_avg_time, td->o.bw_avg_time); continue;