Add option for refilling IO buffers on each submit
authorJens Axboe <jens.axboe@oracle.com>
Wed, 21 May 2008 17:52:35 +0000 (19:52 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 21 May 2008 17:52:35 +0000 (19:52 +0200)
If the device looks at whether the data changed, then this can
make a difference.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
HOWTO
fio.c
fio.h
io_u.c
options.c

diff --git a/HOWTO b/HOWTO
index 32e7322cdc5155d3d6c2a1bf7875acbcd0cb7c2c..36e42aaf6b9defb210d83d0b538284bea7f6a4d6 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -336,6 +336,11 @@ bs_unaligned       If this option is given, any byte size value within bsrange
 zero_buffers   If this option is given, fio will init the IO buffers to
                all zeroes. The default is to fill them with random data.
 
+refill_buffers If this option is given, fio will refill the IO buffers
+               on every submit. The default is to only fill it at init
+               time and reuse that data. Only makes sense if zero_buffers
+               isn't specified, naturally.
+
 nrfiles=int    Number of files to use for this job. Defaults to 1.
 
 openfiles=int  Number of files to keep open at the same time. Defaults to
diff --git a/fio.c b/fio.c
index b79aa93e644296be9bdf0439863760d8dd4a6cfd..c79fad87600d53f4565bcb96c442938883fc5327 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -642,22 +642,6 @@ static void cleanup_io_u(struct thread_data *td)
        free_io_mem(td);
 }
 
-/*
- * "randomly" fill the buffer contents
- */
-static void fill_io_buf(struct thread_data *td, struct io_u *io_u, int max_bs)
-{
-       long *ptr = io_u->buf;
-
-       if (!td->o.zero_buffers) {
-               while ((void *) ptr - io_u->buf < max_bs) {
-                       *ptr = rand() * GOLDEN_RATIO_PRIME;
-                       ptr++;
-               }
-       } else
-               memset(ptr, 0, max_bs);
-}
-
 static int init_io_u(struct thread_data *td)
 {
        struct io_u *io_u;
@@ -700,8 +684,8 @@ static int init_io_u(struct thread_data *td)
                if (!(td->io_ops->flags & FIO_NOIO)) {
                        io_u->buf = p + max_bs * i;
 
-                       if (td_write(td))
-                               fill_io_buf(td, io_u, max_bs);
+                       if (td_write(td) && !td->o.refill_buffers)
+                               io_u_fill_buffer(td, io_u, max_bs);
                }
 
                io_u->index = i;
diff --git a/fio.h b/fio.h
index 47b6d488e66eb7b4026d71933bbdb15a7359ed4d..25d05bdc373fb7b5b8ec4128797dedb29c36b24c 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -478,6 +478,7 @@ struct thread_options {
        unsigned int group_reporting;
        unsigned int fadvise_hint;
        unsigned int zero_buffers;
+       unsigned int refill_buffers;
        unsigned int time_based;
 
        char *read_iolog_file;
@@ -907,6 +908,7 @@ extern void io_u_log_error(struct thread_data *, struct io_u *);
 extern void io_u_init_timeout(void);
 extern void io_u_set_timeout(struct thread_data *);
 extern void io_u_mark_depth(struct thread_data *, unsigned int);
+extern void io_u_fill_buffer(struct thread_data *td, struct io_u *, unsigned int);
 
 /*
  * io engine entry points
diff --git a/io_u.c b/io_u.c
index 92cdd71701a9df3973eb4158b0a8fcb6bab4eed5..06fb3cef80c7fb71c1c6aad29e1936b27e1b9b19 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -6,6 +6,7 @@
 #include <assert.h>
 
 #include "fio.h"
+#include "hash.h"
 
 /*
  * Change this define to play with the timeout handling
@@ -780,6 +781,9 @@ struct io_u *get_io_u(struct thread_data *td)
        io_u->endpos = io_u->offset + io_u->buflen;
        io_u->xfer_buf = io_u->buf;
        io_u->xfer_buflen = io_u->buflen;
+
+       if (td->o.refill_buffers && io_u->ddir == DDIR_WRITE)
+               io_u_fill_buffer(td, io_u, io_u->xfer_buflen);
 out:
        if (!td_io_prep(td, io_u)) {
                fio_gettime(&io_u->start_time, NULL);
@@ -943,6 +947,23 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
        add_slat_sample(td, io_u->ddir, slat_time);
 }
 
+/*
+ * "randomly" fill the buffer contents
+ */
+void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u,
+                     unsigned int max_bs)
+{
+       long *ptr = io_u->buf;
+
+       if (!td->o.zero_buffers) {
+               while ((void *) ptr - io_u->buf < max_bs) {
+                       *ptr = rand() * GOLDEN_RATIO_PRIME;
+                       ptr++;
+               }
+       } else
+               memset(ptr, 0, max_bs);
+}
+
 #ifdef FIO_USE_TIMEOUT
 void io_u_set_timeout(struct thread_data *td)
 {
index 8a6a433833582552983ffadf4b2d9e596aa514d5..ba57e4469d4ab4baf202b51c47702614b767941e 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1215,6 +1215,12 @@ static struct fio_option options[] = {
                .off1   = td_var_offset(zero_buffers),
                .help   = "Init IO buffers to all zeroes",
        },
+       {
+               .name   = "refill_buffers",
+               .type   = FIO_OPT_STR_SET,
+               .off1   = td_var_offset(refill_buffers),
+               .help   = "Refill IO buffers on every IO submit",
+       },
 #ifdef FIO_HAVE_DISK_UTIL
        {
                .name   = "disk_util",