Add 'replay_time_scale' option
authorJens Axboe <axboe@kernel.dk>
Sat, 14 Apr 2018 22:23:33 +0000 (16:23 -0600)
committerJens Axboe <axboe@kernel.dk>
Sat, 14 Apr 2018 22:23:33 +0000 (16:23 -0600)
This allows the user to scale the replay speed of an IO trace. It
defaults to 100, meaning run at 100% the original rate. If set to
50, fio will replay at 50% the original IO rate. If set to 400,
fio will replay at 4x the original rate. And so on.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
HOWTO
blktrace.c
fio.1
options.c
server.h
thread_options.h

diff --git a/HOWTO b/HOWTO
index 5c8623d2cd39ba61794e6674a94ed868494f38b0..68b6b82e3d6a7aad30a22211095eb0d6f0de1d07 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -2311,6 +2311,14 @@ I/O replay
        still respecting ordering. The result is the same I/O pattern to a given
        device, but different timings.
 
+.. option:: replay_time_scale=int
+
+       When replaying I/O with :option:`read_iolog`, fio will honor the
+       original timing in the trace. With this option, it's possible to scale
+       the time. It's a percentage option, if set to 50 it means run at 50%
+       the original IO rate in the trace. If set to 200, run at twice the
+       original IO rate. Defaults to 100.
+
 .. option:: replay_redirect=str
 
        While replaying I/O patterns using :option:`read_iolog` the default behavior
index 6e4d0a4c9620bdabb9000ff45e6bff60e67a2c5f..71ac412ba5e0c3f451967f61dd5405246b957f21 100644 (file)
@@ -333,13 +333,19 @@ static void handle_trace(struct thread_data *td, struct blk_io_trace *t,
                return;
 
        if (!(t->action & BLK_TC_ACT(BLK_TC_NOTIFY))) {
-               if (!last_ttime || td->o.no_stall) {
-                       last_ttime = t->time;
+               if (!last_ttime || td->o.no_stall)
                        delay = 0;
-               } else {
+               else if (td->o.replay_time_scale == 100)
                        delay = t->time - last_ttime;
-                       last_ttime = t->time;
+               else {
+                       double tmp = t->time - last_ttime;
+                       double scale;
+
+                       scale = (double) 100.0 / (double) td->o.replay_time_scale;
+                       tmp *= scale;
+                       delay = tmp;
                }
+               last_ttime = t->time;
        }
 
        t_bytes_align(&td->o, t);
diff --git a/fio.1 b/fio.1
index dd4f9cb49caeedd93b4efbd0484c3e952e6a7827..3b5522f4b6126450f2a1198367ad9355bc91d2bb 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -2036,6 +2036,12 @@ respect the timestamps and attempt to replay them as fast as possible while
 still respecting ordering. The result is the same I/O pattern to a given
 device, but different timings.
 .TP
+.BI replay_time_scale \fR=\fPint
+When replaying I/O with \fBread_iolog\fR, fio will honor the original timing
+in the trace. With this option, it's possible to scale the time. It's a
+percentage option, if set to 50 it means run at 50% the original IO rate in
+the trace. If set to 200, run at twice the original IO rate. Defaults to 100.
+.TP
 .BI replay_redirect \fR=\fPstr
 While replaying I/O patterns using \fBread_iolog\fR the default behavior
 is to replay the IOPS onto the major/minor device that each IOP was recorded
index fae3943423e9c2d02d22e5ffa8c4b00c9fba128e..045c62bd00bb5a4cdc18411332f72efde1f302a9 100644 (file)
--- a/options.c
+++ b/options.c
@@ -3156,6 +3156,19 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .group  = FIO_OPT_G_IOLOG,
                .pow2   = 1,
        },
+       {
+               .name   = "replay_time_scale",
+               .lname  = "Replay Time Scale",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct thread_options, replay_time_scale),
+               .def    = "100",
+               .minval = 1,
+               .parent = "read_iolog",
+               .hide   = 1,
+               .help   = "Scale time for replay events",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IOLOG,
+       },
        {
                .name   = "exec_prerun",
                .lname  = "Pre-execute runnable",
index 1eee7dcf97252b0f40f40ec9c24aa3f5a69e446a..48968603d732b8fb676ff46b70040a26803a4b2c 100644 (file)
--- a/server.h
+++ b/server.h
@@ -48,7 +48,7 @@ struct fio_net_cmd_reply {
 };
 
 enum {
-       FIO_SERVER_VER                  = 71,
+       FIO_SERVER_VER                  = 72,
 
        FIO_SERVER_MAX_FRAGMENT_PDU     = 1024,
        FIO_SERVER_MAX_CMD_MB           = 2048,
index dc290b0ba197e8da091d65f4e711f5f4758f7ab5..944feafaf9281d4aab6fadef94ad29d5b7dfde74 100644 (file)
@@ -317,6 +317,7 @@ struct thread_options {
 
        unsigned int replay_align;
        unsigned int replay_scale;
+       unsigned int replay_time_scale;
 
        unsigned int per_job_logs;
 
@@ -592,6 +593,7 @@ struct thread_options_pack {
 
        uint32_t replay_align;
        uint32_t replay_scale;
+       uint32_t replay_time_scale;
 
        uint32_t per_job_logs;