Add low water mark for queuing depth
authorJens Axboe <jens.axboe@oracle.com>
Tue, 20 Feb 2007 13:37:26 +0000 (14:37 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 20 Feb 2007 13:37:26 +0000 (14:37 +0100)
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>
HOWTO
fio.c
fio.h
init.c

diff --git a/HOWTO b/HOWTO
index ac15fc800f150d61d82d5f278dc3078cc8b0b296..ea98810a211d97328232dfb593f84654cfa2f331 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -294,6 +294,13 @@ iodepth=int        This defines how many io units to keep in flight against
                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.
 
diff --git a/fio.c b/fio.c
index e4fec4f6e0202a041dfd4524f45570a0bdd074de..1c2748e06ee4483b0cdef5457757985140a133a6 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -287,9 +287,13 @@ requeue:
                 * 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) {
                        min_events = 1;
 
                        min_events = 1;
 
+                       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
@@ -411,9 +415,13 @@ requeue:
                 */
                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) {
                                min_evts = 1;
 
                                min_evts = 1;
 
+                               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)
diff --git a/fio.h b/fio.h
index 38de5e3d51370936997c3ba0fe95e548ddb4fcce..282ccf0d1f27935a437061246013e0ea3ee23b40 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -325,6 +325,7 @@ struct thread_data {
        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;
diff --git a/init.c b/init.c
index 6dc221ea4eb31ff95e8796d50aeaf4199845a429..5630c9fb3e821708b6bb8552cd5a3111834c82fb 100644 (file)
--- a/init.c
+++ b/init.c
@@ -90,6 +90,12 @@ static struct fio_option options[] = {
                .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,
@@ -644,6 +650,14 @@ static void fixup_options(struct thread_data *td)
         */
        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);
 }
 
 /*
 }
 
 /*