[PATCH] Add condition to stop issuing io in do_io().

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.
---
 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




[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux