Current fio will attempt to keep the queue full at all times,
but sometimes that's not what you want. Add iodepth_low to
indicate a low water mark for queuing depth, so that when we
see a FIO_Q_BUSY or run out of free requests, let the queue
drain down to the iodepth_low setting before building it up
again.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
job, can be overridden with a larger value for higher
concurrency.
job, can be overridden with a larger value for higher
concurrency.
+iodepth_low=int The low water mark indicating when to start filling
+ the queue again. Defaults to the same as iodepth, meaning
+ that fio will attempt to keep the queue full at all times.
+ If iodepth is set to eg 16 and iodepth_low is set to 4, then
+ after fio has filled the queue of 16 requests, it will let
+ the depth drain down to 4 before starting to fill it again.
+
direct=bool If value is true, use non-buffered io. This is usually
O_DIRECT.
direct=bool If value is true, use non-buffered io. This is usually
O_DIRECT.
* completed io_u's first.
*/
min_events = 0;
* completed io_u's first.
*/
min_events = 0;
- if (queue_full(td) || ret == FIO_Q_BUSY)
+ if (queue_full(td) || ret == FIO_Q_BUSY) {
+ if (td->cur_depth > td->iodepth_low)
+ min_events = td->cur_depth - td->iodepth_low;
+ }
+
/*
* Reap required number of io units, if any, and do the
* verification on them through the callback handler
/*
* Reap required number of io units, if any, and do the
* verification on them through the callback handler
*/
if (ret == FIO_Q_QUEUED || ret == FIO_Q_BUSY) {
min_evts = 0;
*/
if (ret == FIO_Q_QUEUED || ret == FIO_Q_BUSY) {
min_evts = 0;
- if (queue_full(td) || ret == FIO_Q_BUSY)
+ if (queue_full(td) || ret == FIO_Q_BUSY) {
+ if (td->cur_depth > td->iodepth_low)
+ min_evts = td->cur_depth - td->iodepth_low;
+ }
+
fio_gettime(&comp_time, NULL);
bytes_done = io_u_queued_complete(td, min_evts, NULL);
if (bytes_done < 0)
fio_gettime(&comp_time, NULL);
bytes_done = io_u_queued_complete(td, min_evts, NULL);
if (bytes_done < 0)
unsigned int stonewall;
unsigned int numjobs;
unsigned int iodepth;
unsigned int stonewall;
unsigned int numjobs;
unsigned int iodepth;
+ unsigned int iodepth_low;
os_cpu_mask_t cpumask;
unsigned int iolog;
unsigned int read_iolog;
os_cpu_mask_t cpumask;
unsigned int iolog;
unsigned int read_iolog;
.help = "Amount of IO buffers to keep in flight",
.def = "1",
},
.help = "Amount of IO buffers to keep in flight",
.def = "1",
},
+ {
+ .name = "iodepth_low",
+ .type = FIO_OPT_INT,
+ .off1 = td_var_offset(iodepth_low),
+ .help = "Low water mark for queuing depth",
+ },
{
.name = "size",
.type = FIO_OPT_STR_VAL,
{
.name = "size",
.type = FIO_OPT_STR_VAL,
*/
if (td->thinktime_spin > td->thinktime)
td->thinktime_spin = td->thinktime;
*/
if (td->thinktime_spin > td->thinktime)
td->thinktime_spin = td->thinktime;
+
+ /*
+ * The low water mark cannot be bigger than the iodepth
+ */
+ if (td->iodepth_low > td->iodepth || !td->iodepth_low)
+ td->iodepth_low = td->iodepth;
+
+ printf("io depth %d/%d\n", td->iodepth_low, td->iodepth);