The following changes since commit 7d9f80c48c57e9c213a9cd057f29c7823c65918a: Fio 2.0.1 (2012-01-18 09:00:20 +0100) are available in the git repository at: git://git.kernel.dk/fio.git master Jens Axboe (1): Merge branch 'master' of ssh://brick.kernel.dk/data/git/fio Ryan Marchand (1): Fix thread hang when using async engines (libaio,etc.) when too low of a iops rate is specified. Steven Noonan (2): fix early termination of runs caused by ramp_time > runtime implement zoned random I/O testing support fio.c | 2 ++ fio.h | 16 +++++++++++++++- init.c | 11 +++++++++-- io_u.c | 17 +++++++++++++---- ioengines.c | 18 ++++++++++++++---- options.c | 7 +++++++ 6 files changed, 60 insertions(+), 11 deletions(-) --- Diff of recent changes: diff --git a/fio.c b/fio.c index 77e5572..7aa55a8 100644 --- a/fio.c +++ b/fio.c @@ -343,6 +343,8 @@ static int check_min_rate(struct thread_data *td, struct timeval *now, static inline int runtime_exceeded(struct thread_data *td, struct timeval *t) { + if (in_ramp_time(td)) + return 0; if (!td->o.timeout) return 0; if (mtime_since(&td->epoch, t) >= td->o.timeout * 1000) diff --git a/fio.h b/fio.h index afffb9a..c8b94f6 100644 --- a/fio.h +++ b/fio.h @@ -168,6 +168,7 @@ struct thread_options { unsigned int bw_avg_time; unsigned int iops_avg_time; unsigned int loops; + unsigned long long zone_range; unsigned long long zone_size; unsigned long long zone_skip; enum fio_memtype mem_type; @@ -346,10 +347,23 @@ struct thread_data { struct ioengine_ops *io_ops; /* - * Current IO depth and list of free and busy io_u's. + * Queue depth of io_u's that fio MIGHT do */ unsigned int cur_depth; + + /* + * io_u's about to be committed + */ unsigned int io_u_queued; + + /* + * io_u's submitted but not completed yet + */ + unsigned int io_u_in_flight; + + /* + * List of free and busy io_u's + */ struct flist_head io_u_freelist; struct flist_head io_u_busylist; struct flist_head io_u_requeues; diff --git a/init.c b/init.c index 381bb65..4a3716b 100644 --- a/init.c +++ b/init.c @@ -402,12 +402,19 @@ static int fixup_options(struct thread_data *td) } /* - * only really works for sequential io for now, and with 1 file + * only really works with 1 file */ - if (o->zone_size && td_random(td) && o->open_files == 1) + if (o->zone_size && o->open_files == 1) o->zone_size = 0; /* + * If zone_range isn't specified, backward compatibility dictates it + * should be made equal to zone_size. + */ + if (o->zone_size && !o->zone_range) + o->zone_range = o->zone_size; + + /* * Reads can do overwrites, we always need to pre-create the file */ if (td_read(td) || td_rw(td)) diff --git a/io_u.c b/io_u.c index 1aa418c..428b312 100644 --- a/io_u.c +++ b/io_u.c @@ -114,6 +114,9 @@ static unsigned long long last_block(struct thread_data *td, struct fio_file *f, if (max_size > f->real_file_size) max_size = f->real_file_size; + if (td->o.zone_range) + max_size = td->o.zone_range; + max_blocks = max_size / (unsigned long long) td->o.ba[ddir]; if (!max_blocks) return 0; @@ -493,12 +496,17 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir) /* * We are going to sleep, ensure that we flush anything pending as - * not to skew our latency numbers + * not to skew our latency numbers. + * + * Changed to only monitor 'in flight' requests here instead of the + * td->cur_depth, b/c td->cur_depth does not accurately represent + * io's that have been actually submitted to an async engine, + * and cur_depth is meaningless for sync engines. */ - if (td->cur_depth) { + if (td->io_u_in_flight) { int fio_unused ret; - ret = io_u_queued_complete(td, td->cur_depth, NULL); + ret = io_u_queued_complete(td, td->io_u_in_flight, NULL); } fio_gettime(&t, NULL); @@ -656,7 +664,8 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u) */ if (td->zone_bytes >= td->o.zone_size) { td->zone_bytes = 0; - io_u->file->last_pos += td->o.zone_skip; + io_u->file->file_offset += td->o.zone_range + td->o.zone_skip; + io_u->file->last_pos = io_u->file->file_offset; td->io_skip_bytes += td->o.zone_skip; } diff --git a/ioengines.c b/ioengines.c index e8ed871..4c609f2 100644 --- a/ioengines.c +++ b/ioengines.c @@ -222,9 +222,14 @@ int td_io_getevents(struct thread_data *td, unsigned int min, unsigned int max, if (max && td->io_ops->getevents) r = td->io_ops->getevents(td, min, max, t); out: - if (r >= 0) + if (r >= 0) { + /* + * Reflect that our submitted requests were retrieved with + * whatever OS async calls are in the underlying engine. + */ + td->io_u_in_flight -= r; io_u_mark_complete(td, r); - else + } else td_verror(td, r, "get_events"); dprint(FD_IO, "getevents: %d\n", r); @@ -344,14 +349,19 @@ int td_io_commit(struct thread_data *td) if (!td->cur_depth || !td->io_u_queued) return 0; - io_u_mark_depth(td, td->io_u_queued); - td->io_u_queued = 0; + io_u_mark_depth(td, td->io_u_queued); if (td->io_ops->commit) { ret = td->io_ops->commit(td); if (ret) td_verror(td, -ret, "io commit"); } + + /* + * Reflect that events were submitted as async IO requests. + */ + td->io_u_in_flight += td->io_u_queued; + td->io_u_queued = 0; return 0; } diff --git a/options.c b/options.c index f9bd1a4..f62ab6d 100644 --- a/options.c +++ b/options.c @@ -1670,6 +1670,13 @@ static struct fio_option options[FIO_MAX_OPTS] = { .name = "zonesize", .type = FIO_OPT_STR_VAL, .off1 = td_var_offset(zone_size), + .help = "Amount of data to read per zone", + .def = "0", + }, + { + .name = "zonerange", + .type = FIO_OPT_STR_VAL, + .off1 = td_var_offset(zone_range), .help = "Give size of an IO zone", .def = "0", }, -- To unsubscribe from this list: send the line "unsubscribe fio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html