From 002e7183cb86d6100efef690b6fa90bf0988b084 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 17 May 2013 12:39:53 +0200 Subject: [PATCH] Ensure that we have no IO pending when sleeping For rate limiting or thinktime handling, ensure that we have no busy IO when we do spin or sleep. Otherwise we potentially skew the latencies a lot, since events could have been reaped. Already working for rate iops, just abstracted it out and ensure that we do the same for thinktime. Only a problem for certain workloads, those with queuedepth > 1. Signed-off-by: Jens Axboe --- backend.c | 2 ++ io_u.c | 33 +++++++++++++++++++-------------- ioengine.h | 1 + 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/backend.c b/backend.c index 89ffee12..6b6da676 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/io_u.c b/io_u.c index 2cf2b8d0..f0b61705 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 362ab3e5..0be905f9 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); -- 2.25.1