On Mon, Sep 16, 2013 at 9:22 AM, Juan Casse <jcasse@xxxxxxxxxxxx> wrote: > Problem: > When specifying iodepth > 1 while doing random async io > without a random map (and using the default random generator), the > main while loop in do_io() will issue extra io in the amount of io > allowed to accumulate in the queue. For example, a job with size=24k > and bs=8k will perform 4 io instead of the expected 3. > > Reason: > The above behavior occurs because the while loop in do_io() > will continue until the amount of "completed io" >= size, but io > in the queue are not accounted for because they have not been > completed by io_u_queued_complete(). > > Exceptions: > The above behavior does not manifest itself when: > using random_generator=lfsr bacause lfsr knows when to stop > generating, and get_io_u() inside the while loop returns NULL, > breaking out of the loop. > using random map because random map ensures that all blocks > are hit, and after they are all hit, no more are generated. > > Proposed Solution: > Stop while loop based on bytes issued instead of bytes completed. (before Jen's complains about it. :) Signed-off-by: Juan Casse <jcasse@xxxxxxxxxxxx> (he's standing next to me :) Reviewed-by: Grant Grundler <grundler@xxxxxxxxxxxx> Good Catch! :) thanks, grant > --- > backend.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/backend.c b/backend.c > index b9c1c12..180a487 100644 > --- a/backend.c > +++ b/backend.c > @@ -642,6 +642,7 @@ static uint64_t do_io(struct thread_data *td) > uint64_t bytes_done[DDIR_RWDIR_CNT] = { 0, 0, 0 }; > unsigned int i; > int ret = 0; > + uint64_t bytes_issued = 0; > > if (in_ramp_time(td)) > td_set_runstate(td, TD_RAMP); > @@ -675,6 +676,9 @@ static uint64_t do_io(struct thread_data *td) > if (flow_threshold_exceeded(td)) > continue; > > + if (bytes_issued >= (uint64_t) td->o.size) > + break; > + > io_u = get_io_u(td); > if (!io_u) > break; > @@ -708,6 +712,7 @@ static uint64_t do_io(struct thread_data *td) > int bytes = io_u->xfer_buflen - io_u->resid; > struct fio_file *f = io_u->file; > > + bytes_issued += bytes; > /* > * zero read, fail > */ > @@ -738,6 +743,7 @@ sync_done: > ret = io_u_sync_complete(td, io_u, bytes_done); > if (ret < 0) > break; > + bytes_issued += io_u->xfer_buflen; > } > break; > case FIO_Q_QUEUED: > @@ -748,6 +754,7 @@ sync_done: > */ > if (td->io_ops->commit == NULL) > io_u_queued(td, io_u); > + bytes_issued += io_u->xfer_buflen; > break; > case FIO_Q_BUSY: > requeue_io_u(td, &io_u); > -- > 1.7.12.4 > -- 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