Add option to manually seed the random generators
authorJens Axboe <axboe@kernel.dk>
Sat, 11 Jan 2014 03:57:01 +0000 (20:57 -0700)
committerJens Axboe <axboe@kernel.dk>
Sat, 11 Jan 2014 03:57:01 +0000 (20:57 -0700)
Signed-off-by: Jens Axboe <axboe@kernel.dk>
HOWTO
cconv.c
fio.1
init.c
options.c
server.h
thread_options.h

diff --git a/HOWTO b/HOWTO
index 044b57221f3d18c431e4840bfcbdb21bbab31b2e..2183be10205345f85c9eb97305b054f77d60d928 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -384,6 +384,11 @@ unified_rw_reporting=bool  Fio normally reports statistics on a per
 randrepeat=bool        For random IO workloads, seed the generator in a predictable
                way so that results are repeatable across repetitions.
 
+randseed=int   Seed the random number generators based on this seed value, to
+               be able to control what sequence of output is being generated.
+               If not set, the random sequence depends on the randrepeat
+               setting.
+
 use_os_rand=bool Fio can either use the random generator supplied by the OS
                to generator random offsets, or it can use it's own internal
                generator (based on Tausworthe). Default is to use the
diff --git a/cconv.c b/cconv.c
index dd61d103412c192c9edaba105e416f7b1b8041b1..3a6880ac1c59db1416095e357fc5b71f1b9bbb4b 100644 (file)
--- a/cconv.c
+++ b/cconv.c
@@ -118,6 +118,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,
        o->do_disk_util = le32_to_cpu(top->do_disk_util);
        o->override_sync = le32_to_cpu(top->override_sync);
        o->rand_repeatable = le32_to_cpu(top->rand_repeatable);
+       o->rand_seed = le32_to_cpu(top->rand_seed);
        o->use_os_rand = le32_to_cpu(top->use_os_rand);
        o->log_avg_msec = le32_to_cpu(top->log_avg_msec);
        o->norandommap = le32_to_cpu(top->norandommap);
@@ -282,6 +283,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top,
        top->do_disk_util = cpu_to_le32(o->do_disk_util);
        top->override_sync = cpu_to_le32(o->override_sync);
        top->rand_repeatable = cpu_to_le32(o->rand_repeatable);
+       top->rand_seed = cpu_to_le32(o->rand_seed);
        top->use_os_rand = cpu_to_le32(o->use_os_rand);
        top->log_avg_msec = cpu_to_le32(o->log_avg_msec);
        top->norandommap = cpu_to_le32(o->norandommap);
diff --git a/fio.1 b/fio.1
index 9ee0eef1a9e5d711c99a5cc73f09a60de7a2c51f..6c3dd21bab61bea09d839ae984c00a540b2255eb 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -288,6 +288,11 @@ set, the fio will sum the results and report them as "mixed" instead.
 Seed the random number generator in a predictable way so results are repeatable
 across runs.  Default: true.
 .TP
+.BI randseed \fR=\fPint
+Seed the random number generators based on this seed value, to be able to
+control what sequence of output is being generated. If not set, the random
+sequence depends on the \fBrandrepeat\fR setting.
+.TP
 .BI use_os_rand \fR=\fPbool
 Fio can either use the random generator supplied by the OS to generator random
 offsets, or it can use it's own internal generator (based on Tausworthe).
diff --git a/init.c b/init.c
index ba22f785957d86c54523646807445f6db96053f6..af0bb2dbb0099cfae14e4ed657a18ba841075705 100644 (file)
--- a/init.c
+++ b/init.c
@@ -635,6 +635,12 @@ static int fixup_options(struct thread_data *td)
        if (td->o.oatomic)
                td->o.odirect = 1;
 
+       /*
+        * If randseed is set, that overrides randrepeat
+        */
+       if (td->o.rand_seed)
+               td->o.rand_repeatable = 0;
+
        return ret;
 }
 
@@ -830,10 +836,15 @@ static int setup_random_seeds(struct thread_data *td)
        unsigned long seed;
        unsigned int i;
 
-       if (!td->o.rand_repeatable)
+       if (!td->o.rand_repeatable && !td->o.rand_seed)
                return init_random_state(td, td->rand_seeds, sizeof(td->rand_seeds));
 
-       for (seed = 0x89, i = 0; i < 4; i++)
+       if (!td->o.rand_seed)
+               seed = 0x89;
+       else
+               seed = td->o.rand_seed;
+
+       for (i = 0; i < 4; i++)
                seed *= 0x9e370001UL;
 
        for (i = 0; i < FIO_RAND_NR_OFFS; i++) {
index b0f45098285811fead6860af6f0acc2c6cd53ca5..16b6636991d65290bd10f4befbf06c00904dc580 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1626,6 +1626,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_RANDOM,
        },
+       {
+               .name   = "randseed",
+               .lname  = "The random generator seed",
+               .type   = FIO_OPT_INT,
+               .off1   = td_var_offset(rand_seed),
+               .help   = "Set the random generator seed value",
+               .parent = "rw",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_RANDOM,
+       },
        {
                .name   = "use_os_rand",
                .lname  = "Use OS random",
index 84901cf6f176e950771f98bd46047c00018ae4df..0416fd7d7d5be75f6d0fc734e79140c8d109285f 100644 (file)
--- a/server.h
+++ b/server.h
@@ -38,7 +38,7 @@ struct fio_net_cmd_reply {
 };
 
 enum {
-       FIO_SERVER_VER                  = 28,
+       FIO_SERVER_VER                  = 29,
 
        FIO_SERVER_MAX_FRAGMENT_PDU     = 1024,
 
index 7476d8c264d0871e54ec034a01ccb0a4cc1be956..e2c6e88552399a4b2ac88ca164147431822901ef 100644 (file)
@@ -100,6 +100,7 @@ struct thread_options {
        unsigned int do_disk_util;
        unsigned int override_sync;
        unsigned int rand_repeatable;
+       unsigned int rand_seed;
        unsigned int use_os_rand;
        unsigned int log_avg_msec;
        unsigned int norandommap;
@@ -319,6 +320,7 @@ struct thread_options_pack {
        uint32_t do_disk_util;
        uint32_t override_sync;
        uint32_t rand_repeatable;
+       uint32_t rand_seed;
        uint32_t use_os_rand;
        uint32_t log_avg_msec;
        uint32_t norandommap;