The option is pending testing, so not documented yet.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
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;
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
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;
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) {
/*
* "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);
}
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);
*/
+#include <string.h>
+#include <assert.h>
#include "rand.h"
#include "../hash.h"
__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;
+}
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
.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,