Add buffer_compress_percentage
The option is pending testing, so not documented yet.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/backend.c b/backend.c
index 5279104..f3f1030 100644
--- a/backend.c
+++ b/backend.c
@@ -762,12 +762,13 @@
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]);
+ min_write = td->o.min_bs[DDIR_WRITE];
td->orig_buffer_size = (unsigned long long) max_bs
* (unsigned long long) max_units;
@@ -816,7 +817,7 @@
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
diff --git a/fio.h b/fio.h
index 5c912d0..7443bc0 100644
--- a/fio.h
+++ b/fio.h
@@ -194,6 +194,7 @@
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;
diff --git a/io_u.c b/io_u.c
index 161c2cb..2deb5c7 100644
--- a/io_u.c
+++ b/io_u.c
@@ -1227,9 +1227,10 @@
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) {
/*
@@ -1532,12 +1533,18 @@
* "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;
- 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);
}
diff --git a/ioengine.h b/ioengine.h
index 51e5594..efca45e 100644
--- a/ioengine.h
+++ b/ioengine.h
@@ -176,7 +176,7 @@
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);
diff --git a/lib/rand.c b/lib/rand.c
index 7c6fed1..66d0472 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -33,6 +33,8 @@
*/
+#include <string.h>
+#include <assert.h>
#include "rand.h"
#include "../hash.h"
@@ -88,3 +90,43 @@
__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;
+}
diff --git a/lib/rand.h b/lib/rand.h
index 6b9e13c..d62ebe5 100644
--- a/lib/rand.h
+++ b/lib/rand.h
@@ -22,5 +22,6 @@
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
diff --git a/options.c b/options.c
index d777efc..8034cd7 100644
--- a/options.c
+++ b/options.c
@@ -2014,6 +2014,14 @@
.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,
.off1 = td_var_offset(clat_percentiles),