The following changes since commit 9a0ced5a97ae9fde87dae1a3d762b1bc090e8786: sync engine: guard pvsync engine register/unregister (2013-05-16 20:50:26 +0200) are available in the git repository at: git://git.kernel.dk/fio.git master Jens Axboe (4): Ensure that we have no IO pending when sleeping Merge branch 'master' of ssh://git.kernel.dk/data/git/fio Update HOWTO and man page for thinktime blocks impact on queue depth flow: quiesce pending IO before sleep HOWTO | 8 ++++++-- backend.c | 2 ++ fio.1 | 7 ++++++- flow.c | 5 ++++- io_u.c | 33 +++++++++++++++++++-------------- ioengine.h | 1 + 6 files changed, 38 insertions(+), 18 deletions(-) --- Diff of recent changes: diff --git a/HOWTO b/HOWTO index 9b2edb3..794728f 100644 --- a/HOWTO +++ b/HOWTO @@ -830,11 +830,15 @@ thinktime_spin=int to sleeping for the rest of the period specified by thinktime. -thinktime_blocks +thinktime_blocks=int Only valid if thinktime is set - control how many blocks to issue, before waiting 'thinktime' usecs. If not set, defaults to 1 which will make fio wait 'thinktime' usecs - after every block. + after every block. This effectively makes any queue depth + setting redundant, since no more than 1 IO will be queued + before we have to complete it and do our thinktime. In + other words, this setting effectively caps the queue depth + if the latter is larger. rate=int Cap the bandwidth used by this job. The number is in bytes/sec, the normal suffix rules apply. You can use rate=500k to limit diff --git a/backend.c b/backend.c index 89ffee1..6b6da67 100644 --- a/backend.c +++ b/backend.c @@ -822,6 +822,8 @@ sync_done: if (!(b % td->o.thinktime_blocks)) { int left; + io_u_quiesce(td); + if (td->o.thinktime_spin) usec_spin(td->o.thinktime_spin); diff --git a/fio.1 b/fio.1 index f54ea34..91020b2 100644 --- a/fio.1 +++ b/fio.1 @@ -702,7 +702,12 @@ Pretend to spend CPU time for given number of microseconds, sleeping the rest of the time specified by \fBthinktime\fR. Only valid if \fBthinktime\fR is set. .TP .BI thinktime_blocks \fR=\fPint -Number of blocks to issue before waiting \fBthinktime\fR microseconds. +Only valid if thinktime is set - control how many blocks to issue, before +waiting \fBthinktime\fR microseconds. If not set, defaults to 1 which will +make fio wait \fBthinktime\fR microseconds after every block. This +effectively makes any queue depth setting redundant, since no more than 1 IO +will be queued before we have to complete it and do our thinktime. In other +words, this setting effectively caps the queue depth if the latter is larger. Default: 1. .TP .BI rate \fR=\fPint diff --git a/flow.c b/flow.c index b7a2fb1..f9d868d 100644 --- a/flow.c +++ b/flow.c @@ -23,8 +23,11 @@ int flow_threshold_exceeded(struct thread_data *td) sign = td->o.flow > 0 ? 1 : -1; if (sign * flow->flow_counter > td->o.flow_watermark) { - if (td->o.flow_sleep) + if (td->o.flow_sleep) { + io_u_quiesce(td); usleep(td->o.flow_sleep); + } + return 1; } diff --git a/io_u.c b/io_u.c index 2cf2b8d..f0b6170 100644 --- a/io_u.c +++ b/io_u.c @@ -511,6 +511,24 @@ static inline enum fio_ddir get_rand_ddir(struct thread_data *td) return DDIR_WRITE; } +void io_u_quiesce(struct thread_data *td) +{ + /* + * We are going to sleep, ensure that we flush anything pending as + * 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. + */ + while (td->io_u_in_flight) { + int fio_unused ret; + + ret = io_u_queued_complete(td, 1, NULL); + } +} + static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir) { enum fio_ddir odir = ddir ^ 1; @@ -547,20 +565,7 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir) } else usec = td->rate_pending_usleep[ddir]; - /* - * We are going to sleep, ensure that we flush anything pending as - * 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. - */ - while (td->io_u_in_flight) { - int fio_unused ret; - - ret = io_u_queued_complete(td, 1, NULL); - } + io_u_quiesce(td); fio_gettime(&t, NULL); usec_sleep(td, usec); diff --git a/ioengine.h b/ioengine.h index 362ab3e..0be905f 100644 --- a/ioengine.h +++ b/ioengine.h @@ -196,6 +196,7 @@ extern void requeue_io_u(struct thread_data *, struct io_u **); extern int __must_check io_u_sync_complete(struct thread_data *, struct io_u *, uint64_t *); extern int __must_check io_u_queued_complete(struct thread_data *, int, uint64_t *); extern void io_u_queued(struct thread_data *, struct io_u *); +extern void io_u_quiesce(struct thread_data *); extern void io_u_log_error(struct thread_data *, struct io_u *); extern void io_u_mark_depth(struct thread_data *, unsigned int); extern void fill_io_buffer(struct thread_data *, void *, unsigned int, unsigned int); -- 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