Add buffer_compress_percentage
authorJens Axboe <axboe@kernel.dk>
Fri, 2 Mar 2012 20:02:12 +0000 (21:02 +0100)
committerJens Axboe <axboe@kernel.dk>
Fri, 2 Mar 2012 20:02:12 +0000 (21:02 +0100)
The option is pending testing, so not documented yet.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
backend.c
fio.h
io_u.c
ioengine.h
lib/rand.c
lib/rand.h
options.c

index 52791040ff21384d283b2a09de3ff9718e19d866..f3f103038474e3c7e19bd2ece97203080bdab857 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -762,12 +762,13 @@ static void cleanup_io_u(struct thread_data *td)
 static int init_io_u(struct thread_data *td)
 {
        struct io_u *io_u;
 static int init_io_u(struct thread_data *td)
 {
        struct io_u *io_u;
-       unsigned int max_bs;
+       unsigned int max_bs, min_write;
        int cl_align, i, max_units;
        char *p;
 
        max_units = td->o.iodepth;
        max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]);
        int cl_align, i, max_units;
        char *p;
 
        max_units = td->o.iodepth;
        max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]);
+       min_write = td->o.min_bs[DDIR_WRITE];
        td->orig_buffer_size = (unsigned long long) max_bs
                                        * (unsigned long long) max_units;
 
        td->orig_buffer_size = (unsigned long long) max_bs
                                        * (unsigned long long) max_units;
 
@@ -816,7 +817,7 @@ static int init_io_u(struct thread_data *td)
                        dprint(FD_MEM, "io_u %p, mem %p\n", io_u, io_u->buf);
 
                        if (td_write(td))
                        dprint(FD_MEM, "io_u %p, mem %p\n", io_u, io_u->buf);
 
                        if (td_write(td))
-                               io_u_fill_buffer(td, io_u, max_bs);
+                               io_u_fill_buffer(td, io_u, min_write, max_bs);
                        if (td_write(td) && td->o.verify_pattern_bytes) {
                                /*
                                 * Fill the buffer with the pattern if we are
                        if (td_write(td) && td->o.verify_pattern_bytes) {
                                /*
                                 * Fill the buffer with the pattern if we are
diff --git a/fio.h b/fio.h
index 5c912d0aab89da4c3b8c0510e5220107e083a067..7443bc06bdd510f79a5b3a550ea41d6d0e953874 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -194,6 +194,7 @@ struct thread_options {
        unsigned int zero_buffers;
        unsigned int refill_buffers;
        unsigned int scramble_buffers;
        unsigned int zero_buffers;
        unsigned int refill_buffers;
        unsigned int scramble_buffers;
+       unsigned int compress_percentage;
        unsigned int time_based;
        unsigned int disable_lat;
        unsigned int disable_clat;
        unsigned int time_based;
        unsigned int disable_lat;
        unsigned int disable_clat;
diff --git a/io_u.c b/io_u.c
index 161c2cb388d01218628da8468c1fdeba105e40ed..2deb5c7216aea5e02c66cf8237fb7648fc3a2dd2 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -1227,9 +1227,10 @@ struct io_u *get_io_u(struct thread_data *td)
                if (io_u->ddir == DDIR_WRITE) {
                        if (td->o.verify != VERIFY_NONE)
                                populate_verify_io_u(td, io_u);
                if (io_u->ddir == DDIR_WRITE) {
                        if (td->o.verify != VERIFY_NONE)
                                populate_verify_io_u(td, io_u);
-                       else if (td->o.refill_buffers)
-                               io_u_fill_buffer(td, io_u, io_u->xfer_buflen);
-                       else if (td->o.scramble_buffers)
+                       else if (td->o.refill_buffers) {
+                               io_u_fill_buffer(td, io_u,
+                                       io_u->xfer_buflen, io_u->xfer_buflen);
+                       } else if (td->o.scramble_buffers)
                                do_scramble = 1;
                } else if (io_u->ddir == DDIR_READ) {
                        /*
                                do_scramble = 1;
                } else if (io_u->ddir == DDIR_READ) {
                        /*
@@ -1532,12 +1533,18 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
  * "randomly" fill the buffer contents
  */
 void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u,
  * "randomly" fill the buffer contents
  */
 void io_u_fill_buffer(struct thread_data *td, struct io_u *io_u,
-                     unsigned int max_bs)
+                     unsigned int min_write, unsigned int max_bs)
 {
        io_u->buf_filled_len = 0;
 
 {
        io_u->buf_filled_len = 0;
 
-       if (!td->o.zero_buffers)
-               fill_random_buf(&td->buf_state, io_u->buf, max_bs);
-       else
+       if (!td->o.zero_buffers) {
+               unsigned int perc = td->o.compress_percentage;
+
+               if (perc) {
+                       fill_random_buf_percentage(&td->buf_state, io_u->buf,
+                                               perc, min_write, max_bs);
+               } else
+                       fill_random_buf(&td->buf_state, io_u->buf, max_bs);
+       } else
                memset(io_u->buf, 0, max_bs);
 }
                memset(io_u->buf, 0, max_bs);
 }
index 51e559440e6903a33546ee163c83ca7ce0d14480..efca45e2744fd6222cb0b516be793371293dc33e 100644 (file)
@@ -176,7 +176,7 @@ extern int __must_check io_u_queued_complete(struct thread_data *, int, unsigned
 extern void io_u_queued(struct thread_data *, struct io_u *);
 extern void io_u_log_error(struct thread_data *, struct io_u *);
 extern void io_u_mark_depth(struct thread_data *, unsigned int);
 extern void io_u_queued(struct thread_data *, struct io_u *);
 extern void io_u_log_error(struct thread_data *, struct io_u *);
 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);
+extern void io_u_fill_buffer(struct thread_data *td, struct io_u *, unsigned int, unsigned int);
 void io_u_mark_complete(struct thread_data *, unsigned int);
 void io_u_mark_submit(struct thread_data *, unsigned int);
 
 void io_u_mark_complete(struct thread_data *, unsigned int);
 void io_u_mark_submit(struct thread_data *, unsigned int);
 
index 7c6fed1fabbcc01f1803f00521d881a9c9662603..66d04729a49eaa073f822d77a93b66ae426f659d 100644 (file)
@@ -33,6 +33,8 @@
 
 */
 
 
 */
 
+#include <string.h>
+#include <assert.h>
 #include "rand.h"
 #include "../hash.h"
 
 #include "rand.h"
 #include "../hash.h"
 
@@ -88,3 +90,43 @@ unsigned long fill_random_buf(struct frand_state *fs, void *buf,
        __fill_random_buf(buf, len, r);
        return r;
 }
        __fill_random_buf(buf, len, r);
        return r;
 }
+
+unsigned long fill_random_buf_percentage(struct frand_state *fs, void *buf,
+                                        unsigned int percentage,
+                                        unsigned int segment, unsigned int len)
+{
+       unsigned int this_len, rep_len;
+       unsigned long r = __rand(fs);
+
+       assert(segment <= len);
+
+       if (sizeof(int) != sizeof(long *))
+               r *= (unsigned long) __rand(fs);
+
+       while (len) {
+               /*
+                * Fill random chunk
+                */
+               this_len = (segment * (100 - percentage)) / 100;
+               if (this_len > len)
+                       this_len = len;
+
+               __fill_random_buf(buf, this_len, r);
+
+               len -= this_len;
+               buf += this_len;
+
+               /*
+                * Now duplicate random chunk in rest of buf
+                */
+               rep_len = segment - this_len;
+               if (rep_len > len)
+                       rep_len = len;
+
+               memcpy(buf, buf + rep_len, rep_len);
+               buf += rep_len;
+               len -= rep_len;
+       }
+
+       return r;
+}
index 6b9e13c03acd77895d1fbe32e2dd88de10cbfa26..d62ebe5f7ecb95005561c5021df45ab92a06a1d1 100644 (file)
@@ -22,5 +22,6 @@ extern void init_rand(struct frand_state *);
 extern void init_rand_seed(struct frand_state *, unsigned int seed);
 extern void __fill_random_buf(void *buf, unsigned int len, unsigned long seed);
 extern unsigned long fill_random_buf(struct frand_state *, void *buf, unsigned int len);
 extern void init_rand_seed(struct frand_state *, unsigned int seed);
 extern void __fill_random_buf(void *buf, unsigned int len, unsigned long seed);
 extern unsigned long fill_random_buf(struct frand_state *, void *buf, unsigned int len);
+extern unsigned long fill_random_buf_percentage(struct frand_state *, void *buf, unsigned int percentage, unsigned int segment, unsigned int len);
 
 #endif
 
 #endif
index d777efc7efe8293320ed3ff2f529f31047af21a2..8034cd7dad755b58c5f546e64fb083be79ec49a4 100644 (file)
--- a/options.c
+++ b/options.c
@@ -2013,6 +2013,14 @@ static struct fio_option options[FIO_MAX_OPTS] = {
                .help   = "Slightly scramble buffers on every IO submit",
                .def    = "1",
        },
                .help   = "Slightly scramble buffers on every IO submit",
                .def    = "1",
        },
+       {
+               .name   = "buffer_compress_percentage",
+               .type   = FIO_OPT_INT,
+               .off1   = td_var_offset(compress_percentage),
+               .maxval = 100,
+               .minval = 1,
+               .help   = "How compressible the buffer is (approximately)",
+       },
        {
                .name   = "clat_percentiles",
                .type   = FIO_OPT_BOOL,
        {
                .name   = "clat_percentiles",
                .type   = FIO_OPT_BOOL,