Use specified buffer_pattern (if given) for all io_u fills
authorJens Axboe <axboe@fb.com>
Thu, 4 Dec 2014 02:55:33 +0000 (19:55 -0700)
committerJens Axboe <axboe@fb.com>
Thu, 4 Dec 2014 02:55:33 +0000 (19:55 -0700)
For compression, we use a fixed '0' pattern. But if the user
specified a pattern to use in the job file, then we should
use that instead. It could slightly skew the compression ratio
for long patterns, but that is to be expected.

Signed-off-by: Jens Axboe <axboe@fb.com>
HOWTO
fio.1
io_u.c
lib/rand.c
lib/rand.h
verify.c

diff --git a/HOWTO b/HOWTO
index c73b9ecdc859a8912718968918fe837543a258b7..57d3fb7f1e4de2484e071d428eab3f66de1038c4 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -594,9 +594,12 @@ scramble_buffers=bool      If refill_buffers is too costly and the target is
 buffer_compress_percentage=int If this is set, then fio will attempt to
                provide IO buffer content (on WRITEs) that compress to
                the specified level. Fio does this by providing a mix of
 buffer_compress_percentage=int If this is set, then fio will attempt to
                provide IO buffer content (on WRITEs) that compress to
                the specified level. Fio does this by providing a mix of
-               random data and zeroes. Note that this is per block size
-               unit, for file/disk wide compression level that matches
-               this setting, you'll also want to set refill_buffers.
+               random data and a fixed pattern. The fixed pattern is either
+               zeroes, or the pattern specified by buffer_pattern. If the
+               pattern option is used, it might skew the compression ratio
+               slightly. Note that this is per block size unit, for file/disk
+               wide compression level that matches this setting, you'll also
+               want to set refill_buffers.
 
 buffer_compress_chunk=int      See buffer_compress_percentage. This
                setting allows fio to manage how big the ranges of random
 
 buffer_compress_chunk=int      See buffer_compress_percentage. This
                setting allows fio to manage how big the ranges of random
diff --git a/fio.1 b/fio.1
index 77faa45ba125eac84ffcef72c1de766fd3b8fdac..c3193a21e704dd1fb363f2a54a407b8de7a1b820 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -476,9 +476,12 @@ of blocks. Default: true.
 .BI buffer_compress_percentage \fR=\fPint
 If this is set, then fio will attempt to provide IO buffer content (on WRITEs)
 that compress to the specified level. Fio does this by providing a mix of
 .BI buffer_compress_percentage \fR=\fPint
 If this is set, then fio will attempt to provide IO buffer content (on WRITEs)
 that compress to the specified level. Fio does this by providing a mix of
-random data and zeroes. Note that this is per block size unit, for file/disk
-wide compression level that matches this setting, you'll also want to set
-\fBrefill_buffers\fR.
+random data and a fixed pattern. The fixed pattern is either zeroes, or the
+pattern specified by \fBbuffer_pattern\fR. If the pattern option is used, it
+might skew the compression ratio slightly. Note that this is per block size
+unit, for file/disk wide compression level that matches this setting. Note
+that this is per block size unit, for file/disk wide compression level that
+matches this setting, you'll also want to set refill_buffers.
 .TP
 .BI buffer_compress_chunk \fR=\fPint
 See \fBbuffer_compress_percentage\fR. This setting allows fio to manage how
 .TP
 .BI buffer_compress_chunk \fR=\fPint
 See \fBbuffer_compress_percentage\fR. This setting allows fio to manage how
diff --git a/io_u.c b/io_u.c
index 33c82f2c4e9e85f692be0c03a0f1c241dd4539c2..f1359083528600a17185bd06252430514d053a6c 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -1859,9 +1859,9 @@ static void save_buf_state(struct thread_data *td, struct frand_state *rs)
 void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                    unsigned int max_bs)
 {
 void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                    unsigned int max_bs)
 {
-       if (td->o.buffer_pattern_bytes)
-               fill_buffer_pattern(td, buf, max_bs);
-       else if (!td->o.zero_buffers) {
+       struct thread_options *o = &td->o;
+
+       if (o->compress_percentage) {
                unsigned int perc = td->o.compress_percentage;
                struct frand_state *rs;
                unsigned int left = max_bs;
                unsigned int perc = td->o.compress_percentage;
                struct frand_state *rs;
                unsigned int left = max_bs;
@@ -1879,7 +1879,8 @@ void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                                        seg = min_write;
 
                                fill_random_buf_percentage(rs, buf, perc, seg,
                                        seg = min_write;
 
                                fill_random_buf_percentage(rs, buf, perc, seg,
-                                                               min_write);
+                                       min_write, o->buffer_pattern,
+                                                  o->buffer_pattern_bytes);
                        } else
                                fill_random_buf(rs, buf, min_write);
 
                        } else
                                fill_random_buf(rs, buf, min_write);
 
@@ -1887,7 +1888,9 @@ void fill_io_buffer(struct thread_data *td, void *buf, unsigned int min_write,
                        left -= min_write;
                        save_buf_state(td, rs);
                } while (left);
                        left -= min_write;
                        save_buf_state(td, rs);
                } while (left);
-       } else
+       } else if (o->buffer_pattern_bytes)
+               fill_buffer_pattern(td, buf, max_bs);
+       else
                memset(buf, 0, max_bs);
 }
 
                memset(buf, 0, max_bs);
 }
 
index a79fb9c17c321a94e8e4bcfe030193003c80d93f..e5332bfe792492651e7685c4cd35595ca981ddf0 100644 (file)
@@ -34,6 +34,7 @@
 */
 
 #include <string.h>
 */
 
 #include <string.h>
+#include <assert.h>
 #include "rand.h"
 #include "../hash.h"
 
 #include "rand.h"
 #include "../hash.h"
 
@@ -90,15 +91,45 @@ unsigned long fill_random_buf(struct frand_state *fs, void *buf,
        return r;
 }
 
        return r;
 }
 
+void fill_pattern(void *p, unsigned int len, char *pattern,
+                 unsigned int pattern_bytes)
+{
+       switch (pattern_bytes) {
+       case 0:
+               assert(0);
+               break;
+       case 1:
+               memset(p, pattern[0], len);
+               break;
+       default: {
+               unsigned int i = 0, size = 0;
+               unsigned char *b = p;
+
+               while (i < len) {
+                       size = pattern_bytes;
+                       if (size > (len - i))
+                               size = len - i;
+                       memcpy(b+i, pattern, size);
+                       i += size;
+               }
+               break;
+               }
+       }
+}
+
 unsigned long fill_random_buf_percentage(struct frand_state *fs, void *buf,
                                         unsigned int percentage,
 unsigned long fill_random_buf_percentage(struct frand_state *fs, void *buf,
                                         unsigned int percentage,
-                                        unsigned int segment, unsigned int len)
+                                        unsigned int segment, unsigned int len,
+                                        char *pattern, unsigned int pbytes)
 {
        unsigned long r = __rand(fs);
        unsigned int this_len;
 
        if (percentage == 100) {
 {
        unsigned long r = __rand(fs);
        unsigned int this_len;
 
        if (percentage == 100) {
-               memset(buf, 0, len);
+               if (pbytes)
+                       fill_pattern(buf, len, pattern, pbytes);
+               else
+                       memset(buf, 0, len);
                return 0;
        }
 
                return 0;
        }
 
@@ -124,7 +155,10 @@ unsigned long fill_random_buf_percentage(struct frand_state *fs, void *buf,
                if (this_len > len)
                        this_len = len;
 
                if (this_len > len)
                        this_len = len;
 
-               memset(buf, 0, this_len);
+               if (pbytes)
+                       fill_pattern(buf, this_len, pattern, pbytes);
+               else
+                       memset(buf, 0, this_len);
                len -= this_len;
                buf += this_len;
        }
                len -= this_len;
                buf += this_len;
        }
index 8c35ab1fa2636655ca17cd0f868b8c2ffafd0336..803bea484757aa8ef30bf5f63a1f24c43192c7ae 100644 (file)
@@ -30,6 +30,7 @@ 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);
+extern unsigned long fill_random_buf_percentage(struct frand_state *, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int);
+extern void fill_pattern(void *p, unsigned int len, char *pattern, unsigned int pattern_bytes);
 
 #endif
 
 #endif
index c2b3c40edef83619b4937a8de058915a6e8e5192..c1791fc69743c08d40fbdaebdda122545b93037c 100644 (file)
--- a/verify.c
+++ b/verify.c
@@ -29,36 +29,6 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u,
                         struct verify_header *hdr, unsigned int header_num,
                         unsigned int header_len);
 
                         struct verify_header *hdr, unsigned int header_num,
                         unsigned int header_len);
 
-static void fill_pattern(void *p, unsigned int len, char *pattern,
-                        unsigned int pattern_bytes)
-{
-       switch (pattern_bytes) {
-       case 0:
-               assert(0);
-               break;
-       case 1:
-               dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len);
-               memset(p, pattern[0], len);
-               break;
-       default: {
-               unsigned int i = 0, size = 0;
-               unsigned char *b = p;
-
-               dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n",
-                                       pattern_bytes, len);
-
-               while (i < len) {
-                       size = pattern_bytes;
-                       if (size > (len - i))
-                               size = len - i;
-                       memcpy(b+i, pattern, size);
-                       i += size;
-               }
-               break;
-               }
-       }
-}
-
 void fill_buffer_pattern(struct thread_data *td, void *p, unsigned int len)
 {
        fill_pattern(p, len, td->o.buffer_pattern, td->o.buffer_pattern_bytes);
 void fill_buffer_pattern(struct thread_data *td, void *p, unsigned int len)
 {
        fill_pattern(p, len, td->o.buffer_pattern, td->o.buffer_pattern_bytes);