log: add support for logging max instead of averages
authorJens Axboe <axboe@fb.com>
Thu, 4 Feb 2016 19:09:48 +0000 (12:09 -0700)
committerJens Axboe <axboe@fb.com>
Thu, 4 Feb 2016 19:09:48 +0000 (12:09 -0700)
If we log with lov_avg_msec, fio will log the average over that
period of time to the log. Add log_max_value to change this to
logging maximums over the windowed period instead.

Signed-off-by: Jens Axboe <axboe@fb.com>
HOWTO
cconv.c
fio.1
options.c
server.h
stat.c
thread_options.h

diff --git a/HOWTO b/HOWTO
index 4a910a1ac11716d57c3885cf2c2f4fd63f0fa944..6d80360574e0c89899756cbc6a1d9838293c9c81 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -1570,8 +1570,12 @@ log_avg_msec=int By default, fio will log an entry in the iops, latency,
                disk log, that can quickly grow to a very large size. Setting
                this option makes fio average the each log entry over the
                specified period of time, reducing the resolution of the log.
                disk log, that can quickly grow to a very large size. Setting
                this option makes fio average the each log entry over the
                specified period of time, reducing the resolution of the log.
-               Defaults to 0.
+               See log_max as well. Defaults to 0, logging all entries.
 
 
+log_max=bool   If log_avg_msec is set, fio logs the average over that window.
+               If you instead want to log the maximum value, set this option
+               to 1. Defaults to 0, meaning that averaged values are logged.
+.
 log_offset=int If this is set, the iolog options will include the byte
                offset for the IO entry as well as the other data values.
 
 log_offset=int If this is set, the iolog options will include the byte
                offset for the IO entry as well as the other data values.
 
diff --git a/cconv.c b/cconv.c
index 6d8d0b3e336363c8eff7f57b4e18ad68d914ae9b..6f57d90ca8e2f137ab6f2f72c3e6d311223c71ee 100644 (file)
--- a/cconv.c
+++ b/cconv.c
@@ -160,6 +160,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,
        o->allrand_repeatable = le32_to_cpu(top->allrand_repeatable);
        o->rand_seed = le64_to_cpu(top->rand_seed);
        o->log_avg_msec = le32_to_cpu(top->log_avg_msec);
        o->allrand_repeatable = le32_to_cpu(top->allrand_repeatable);
        o->rand_seed = le64_to_cpu(top->rand_seed);
        o->log_avg_msec = le32_to_cpu(top->log_avg_msec);
+       o->log_max = le32_to_cpu(top->log_max);
        o->log_offset = le32_to_cpu(top->log_offset);
        o->log_gz = le32_to_cpu(top->log_gz);
        o->log_gz_store = le32_to_cpu(top->log_gz_store);
        o->log_offset = le32_to_cpu(top->log_offset);
        o->log_gz = le32_to_cpu(top->log_gz);
        o->log_gz_store = le32_to_cpu(top->log_gz_store);
@@ -348,6 +349,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top,
        top->allrand_repeatable = cpu_to_le32(o->allrand_repeatable);
        top->rand_seed = __cpu_to_le64(o->rand_seed);
        top->log_avg_msec = cpu_to_le32(o->log_avg_msec);
        top->allrand_repeatable = cpu_to_le32(o->allrand_repeatable);
        top->rand_seed = __cpu_to_le64(o->rand_seed);
        top->log_avg_msec = cpu_to_le32(o->log_avg_msec);
+       top->log_max = cpu_to_le32(o->log_max);
        top->log_offset = cpu_to_le32(o->log_offset);
        top->log_gz = cpu_to_le32(o->log_gz);
        top->log_gz_store = cpu_to_le32(o->log_gz_store);
        top->log_offset = cpu_to_le32(o->log_offset);
        top->log_gz = cpu_to_le32(o->log_gz);
        top->log_gz_store = cpu_to_le32(o->log_gz_store);
diff --git a/fio.1 b/fio.1
index 6cc6379e14bc7718362d00fe226f9a4f2cb51cb4..246bcd25d22c050e3a8c7054fba3a4277105035d 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -1423,8 +1423,13 @@ then the filename will not include the job index.
 By default, fio will log an entry in the iops, latency, or bw log for every
 IO that completes. When writing to the disk log, that can quickly grow to a
 very large size. Setting this option makes fio average the each log entry
 By default, fio will log an entry in the iops, latency, or bw log for every
 IO that completes. When writing to the disk log, that can quickly grow to a
 very large size. Setting this option makes fio average the each log entry
-over the specified period of time, reducing the resolution of the log.
-Defaults to 0.
+over the specified period of time, reducing the resolution of the log. See
+\fBlog_max\fR as well.  Defaults to 0, logging all entries.
+.TP
+.BI log_max \fR=\fPbool
+If \fBlog_avg_msec\fR is set, fio logs the average over that window. If you
+instead want to log the maximum value, set this option to 1.  Defaults to
+0, meaning that averaged values are logged.
 .TP
 .BI log_offset \fR=\fPbool
 If this is set, the iolog options will include the byte offset for the IO
 .TP
 .BI log_offset \fR=\fPbool
 If this is set, the iolog options will include the byte offset for the IO
index 0bf1390a0d9f19c4f99d9f3e44582aca446e1c67..390208729f0db12955cc3a19f72f1d04d9a40b1f 100644 (file)
--- a/options.c
+++ b/options.c
@@ -3073,6 +3073,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_LOG,
                .group  = FIO_OPT_G_INVALID,
        },
                .category = FIO_OPT_C_LOG,
                .group  = FIO_OPT_G_INVALID,
        },
+       {
+               .name   = "log_max_value",
+               .lname  = "Log maximum instead of average",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(log_max),
+               .help   = "Log max sample in a window instead of average",
+               .def    = "0",
+               .category = FIO_OPT_C_LOG,
+               .group  = FIO_OPT_G_INVALID,
+       },
        {
                .name   = "log_offset",
                .lname  = "Log offset of IO",
        {
                .name   = "log_offset",
                .lname  = "Log offset of IO",
index 05f98e56070c109ae5cd91a6c1dfe7bfb3e5e008..a72689479b31016997c3f8d04957903c483437b5 100644 (file)
--- a/server.h
+++ b/server.h
@@ -38,7 +38,7 @@ struct fio_net_cmd_reply {
 };
 
 enum {
 };
 
 enum {
-       FIO_SERVER_VER                  = 51,
+       FIO_SERVER_VER                  = 52,
 
        FIO_SERVER_MAX_FRAGMENT_PDU     = 1024,
        FIO_SERVER_MAX_CMD_MB           = 2048,
 
        FIO_SERVER_MAX_FRAGMENT_PDU     = 1024,
        FIO_SERVER_MAX_CMD_MB           = 2048,
diff --git a/stat.c b/stat.c
index 73fd9f9eabc8182bc365293948aba08640b467db..d2720a4b1a177de4d8f70480ff50cfec41db01c3 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -1943,7 +1943,7 @@ void reset_io_stats(struct thread_data *td)
 }
 
 static void __add_stat_to_log(struct io_log *iolog, enum fio_ddir ddir,
 }
 
 static void __add_stat_to_log(struct io_log *iolog, enum fio_ddir ddir,
-                             unsigned long elapsed)
+                             unsigned long elapsed, bool log_max)
 {
        /*
         * Note an entry in the log. Use the mean from the logged samples,
 {
        /*
         * Note an entry in the log. Use the mean from the logged samples,
@@ -1953,19 +1953,24 @@ static void __add_stat_to_log(struct io_log *iolog, enum fio_ddir ddir,
        if (iolog->avg_window[ddir].samples) {
                unsigned long val;
 
        if (iolog->avg_window[ddir].samples) {
                unsigned long val;
 
-               val = iolog->avg_window[ddir].mean.u.f + 0.50;
+               if (log_max)
+                       val = iolog->avg_window[ddir].max_val;
+               else
+                       val = iolog->avg_window[ddir].mean.u.f + 0.50;
+
                __add_log_sample(iolog, val, ddir, 0, elapsed, 0);
        }
 
        reset_io_stat(&iolog->avg_window[ddir]);
 }
 
                __add_log_sample(iolog, val, ddir, 0, elapsed, 0);
        }
 
        reset_io_stat(&iolog->avg_window[ddir]);
 }
 
-static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed)
+static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed,
+                            bool log_max)
 {
        int ddir;
 
        for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++)
 {
        int ddir;
 
        for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++)
-               __add_stat_to_log(iolog, ddir, elapsed);
+               __add_stat_to_log(iolog, ddir, elapsed, log_max);
 }
 
 static void add_log_sample(struct thread_data *td, struct io_log *iolog,
 }
 
 static void add_log_sample(struct thread_data *td, struct io_log *iolog,
@@ -2001,7 +2006,7 @@ static void add_log_sample(struct thread_data *td, struct io_log *iolog,
        if (this_window < iolog->avg_msec)
                return;
 
        if (this_window < iolog->avg_msec)
                return;
 
-       _add_stat_to_log(iolog, elapsed);
+       _add_stat_to_log(iolog, elapsed, td->o.log_max != 0);
 
        iolog->avg_last = elapsed;
 }
 
        iolog->avg_last = elapsed;
 }
@@ -2013,15 +2018,15 @@ void finalize_logs(struct thread_data *td)
        elapsed = mtime_since_now(&td->epoch);
 
        if (td->clat_log)
        elapsed = mtime_since_now(&td->epoch);
 
        if (td->clat_log)
-               _add_stat_to_log(td->clat_log, elapsed);
+               _add_stat_to_log(td->clat_log, elapsed, td->o.log_max != 0);
        if (td->slat_log)
        if (td->slat_log)
-               _add_stat_to_log(td->slat_log, elapsed);
+               _add_stat_to_log(td->slat_log, elapsed, td->o.log_max != 0);
        if (td->lat_log)
        if (td->lat_log)
-               _add_stat_to_log(td->lat_log, elapsed);
+               _add_stat_to_log(td->lat_log, elapsed, td->o.log_max != 0);
        if (td->bw_log)
        if (td->bw_log)
-               _add_stat_to_log(td->bw_log, elapsed);
+               _add_stat_to_log(td->bw_log, elapsed, td->o.log_max != 0);
        if (td->iops_log)
        if (td->iops_log)
-               _add_stat_to_log(td->iops_log, elapsed);
+               _add_stat_to_log(td->iops_log, elapsed, td->o.log_max != 0);
 }
 
 void add_agg_sample(unsigned long val, enum fio_ddir ddir, unsigned int bs)
 }
 
 void add_agg_sample(unsigned long val, enum fio_ddir ddir, unsigned int bs)
index 858f307762256695e15752e0a157667f13e00311..384534add7378d88e840c12c2c0a2522e84d562c 100644 (file)
@@ -120,6 +120,7 @@ struct thread_options {
        unsigned long long rand_seed;
        unsigned int dep_use_os_rand;
        unsigned int log_avg_msec;
        unsigned long long rand_seed;
        unsigned int dep_use_os_rand;
        unsigned int log_avg_msec;
+       unsigned int log_max;
        unsigned int log_offset;
        unsigned int log_gz;
        unsigned int log_gz_store;
        unsigned int log_offset;
        unsigned int log_gz;
        unsigned int log_gz_store;
@@ -369,6 +370,7 @@ struct thread_options_pack {
        uint64_t rand_seed;
        uint32_t dep_use_os_rand;
        uint32_t log_avg_msec;
        uint64_t rand_seed;
        uint32_t dep_use_os_rand;
        uint32_t log_avg_msec;
+       uint32_t log_max;
        uint32_t log_offset;
        uint32_t log_gz;
        uint32_t log_gz_store;
        uint32_t log_offset;
        uint32_t log_gz;
        uint32_t log_gz_store;
@@ -380,6 +382,7 @@ struct thread_options_pack {
 
        uint32_t random_distribution;
        uint32_t exitall_error;
 
        uint32_t random_distribution;
        uint32_t exitall_error;
+       uint32_t pad0;
 
        fio_fp64_t zipf_theta;
        fio_fp64_t pareto_h;
 
        fio_fp64_t zipf_theta;
        fio_fp64_t pareto_h;
@@ -397,6 +400,7 @@ struct thread_options_pack {
        uint32_t fsync_blocks;
        uint32_t fdatasync_blocks;
        uint32_t barrier_blocks;
        uint32_t fsync_blocks;
        uint32_t fdatasync_blocks;
        uint32_t barrier_blocks;
+       uint32_t pad1;
        uint64_t start_delay;
        uint64_t start_delay_high;
        uint64_t timeout;
        uint64_t start_delay;
        uint64_t start_delay_high;
        uint64_t timeout;
@@ -461,6 +465,7 @@ struct thread_options_pack {
        uint64_t trim_backlog;
        uint32_t clat_percentiles;
        uint32_t percentile_precision;
        uint64_t trim_backlog;
        uint32_t clat_percentiles;
        uint32_t percentile_precision;
+       uint32_t pad2;
        fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
 
        uint8_t read_iolog_file[FIO_TOP_STR_MAX];
        fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
 
        uint8_t read_iolog_file[FIO_TOP_STR_MAX];
@@ -483,7 +488,6 @@ struct thread_options_pack {
        uint32_t rate_iops[DDIR_RWDIR_CNT];
        uint32_t rate_iops_min[DDIR_RWDIR_CNT];
        uint32_t rate_process;
        uint32_t rate_iops[DDIR_RWDIR_CNT];
        uint32_t rate_iops_min[DDIR_RWDIR_CNT];
        uint32_t rate_process;
-       uint32_t padding_0;   /* for alignment assert */
 
        uint8_t ioscheduler[FIO_TOP_STR_MAX];
 
 
        uint8_t ioscheduler[FIO_TOP_STR_MAX];
 
@@ -516,6 +520,7 @@ struct thread_options_pack {
        uint64_t number_ios;
 
        uint32_t sync_file_range;
        uint64_t number_ios;
 
        uint32_t sync_file_range;
+       uint32_t pad3;
 
        uint64_t latency_target;
        uint64_t latency_window;
 
        uint64_t latency_target;
        uint64_t latency_window;