Recent changes (master)
The following changes since commit 5fa4aff59e4eec471b2c534702f0162006845c4b:
Merge branch 'epoch-time-hist-logs' of https://github.com/parallel-fs-utils/fio (2018-09-19 09:42:47 -0600)
are available in the git repository at:
git://git.kernel.dk/fio.git master
for you to fetch changes up to 4d2707ef027cc5b2418ab5de622318e0f70c096a:
blktrace: fix leak of 'merge_buf' (2018-09-20 14:25:56 -0600)
----------------------------------------------------------------
Dennis Zhou (4):
options: rename name string operations for more general use
blktrace: add support to interleave blktrace files
blktrace: add option to scale a trace
blktrace: add option to iterate over a trace multiple times
Jens Axboe (2):
blktrace: provide empty merge_blktrace_iologs()
blktrace: fix leak of 'merge_buf'
HOWTO | 71 +++++++++++++++++++ blktrace.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ blktrace.h | 22 ++++++ cconv.c | 15 ++++ fio.1 | 66 +++++++++++++++++ init.c | 21 ++++++ options.c | 47 ++++++++++--- options.h | 2 + server.h | 2 +- thread_options.h | 6 ++ 10 files changed, 453 insertions(+), 10 deletions(-)
---
Diff of recent changes:
HOWTO +71 -0
@@ -100,6 +100,10 @@ Command line options Parse options only, don't start any I/O. +.. option:: --merge-blktrace-only + + Merge blktraces only, don't start any I/O. + .. option:: --output=filename Write output to file `filename`.
@@ -2491,6 +2495,33 @@ I/O replay will be read at once. If selected true, input from iolog will be read gradually. Useful when iolog is very large, or it is generated. +.. option:: merge_blktrace_file=str + + When specified, rather than replaying the logs passed to :option:`read_iolog`, + the logs go through a merge phase which aggregates them into a single + blktrace. The resulting file is then passed on as the :option:`read_iolog` + parameter. The intention here is to make the order of events consistent. + This limits the influence of the scheduler compared to replaying multiple + blktraces via concurrent jobs. + +.. option:: merge_blktrace_scalars=float_list + + This is a percentage based option that is index paired with the list of + files passed to :option:`read_iolog`. When merging is performed, scale + the time of each event by the corresponding amount. For example, + ``--merge_blktrace_scalars="50:100"`` runs the first trace in halftime + and the second trace in realtime. This knob is separately tunable from + :option:`replay_time_scale` which scales the trace during runtime and + does not change the output of the merge unlike this option. + +.. option:: merge_blktrace_iters=float_list + + This is a whole number option that is index paired with the list of files + passed to :option:`read_iolog`. When merging is performed, run each trace + for the specified number of iterations. For example, + ``--merge_blktrace_iters="2:1"`` runs the first trace for two iterations + and the second trace for one iteration. + .. option:: replay_no_stall=bool When replaying I/O with :option:`read_iolog` the default behavior is to
@@ -3839,6 +3870,46 @@ given in bytes. The `action` can be one of these: **trim** Trim the given file from the given `offset` for `length` bytes. + +I/O Replay - Merging Traces +--------------------------- + +Colocation is a common practice used to get the most out of a machine. +Knowing which workloads play nicely with each other and which ones don't is +a much harder task. While fio can replay workloads concurrently via multiple +jobs, it leaves some variability up to the scheduler making results harder to +reproduce. Merging is a way to make the order of events consistent. + +Merging is integrated into I/O replay and done when a +:option:`merge_blktrace_file` is specified. The list of files passed to +:option:`read_iolog` go through the merge process and output a single file +stored to the specified file. The output file is passed on as if it were the +only file passed to :option:`read_iolog`. An example would look like:: + + $ fio --read_iolog="<file1>:<file2>" --merge_blktrace_file="<output_file>" + +Creating only the merged file can be done by passing the command line argument +:option:`merge-blktrace-only`. + +Scaling traces can be done to see the relative impact of any particular trace +being slowed down or sped up. :option:`merge_blktrace_scalars` takes in a colon +separated list of percentage scalars. It is index paired with the files passed +to :option:`read_iolog`. + +With scaling, it may be desirable to match the running time of all traces. +This can be done with :option:`merge_blktrace_iters`. It is index paired with +:option:`read_iolog` just like :option:`merge_blktrace_scalars`. + +In an example, given two traces, A and B, each 60s long. If we want to see +the impact of trace A issuing IOs twice as fast and repeat trace A over the +runtime of trace B, the following can be done:: + + $ fio --read_iolog="<trace_a>:"<trace_b>" --merge_blktrace_file"<output_file>" --merge_blktrace_scalars="50:100" --merge_blktrace_iters="2:1" + +This runs trace A at 2x the speed twice for approximately the same runtime as +a single run of trace B. + + CPU idleness profiling ----------------------
blktrace.c +211 -0
220 lines not on this page · raw message
blktrace.h +22 -0
@@ -1,10 +1,27 @@#ifndef FIO_BLKTRACE_H #define FIO_BLKTRACE_H +#ifdef FIO_HAVE_BLKTRACE +#include <asm/types.h> + +#include "blktrace_api.h" + +struct blktrace_cursor { +struct fifo *fifo;// fifo queue for reading +int fd;// blktrace file +__u64 length;// length of trace +struct blk_io_trace t;// current io trace +int swap;// bitwise reverse required +int scalar;// scale percentage +int iter;// current iteration +int nr_iter;// number of iterations to run +}; +bool is_blktrace (const char *,int *);bool load_blktrace (struct thread_data *,const char *,int ); +int merge_blktrace_iologs (struct thread_data *td);#else
@@ -19,5 +36,10 @@ static inline bool load_blktrace(struct thread_data *td, const char *fname,return false; } +static inline int merge_blktrace_iologs (struct thread_data *td) +{ +return false; +} +#endif #endif
cconv.c +15 -0
@@ -37,6 +37,7 @@ static void free_thread_options_to_cpu(struct thread_options *o)free (o->mmapfile);free (o->read_iolog_file);free (o->write_iolog_file); +free (o->merge_blktrace_file);free (o->bw_log_file);free (o->lat_log_file);free (o->iops_log_file);
@@ -73,6 +74,7 @@ void convert_thread_options_to_cpu(struct thread_options *o,string_to_cpu (&o->mmapfile, top->mmapfile);string_to_cpu (&o->read_iolog_file, top->read_iolog_file);string_to_cpu (&o->write_iolog_file, top->write_iolog_file); +string_to_cpu (&o->merge_blktrace_file, top->merge_blktrace_file);string_to_cpu (&o->bw_log_file, top->bw_log_file);string_to_cpu (&o->lat_log_file, top->lat_log_file);string_to_cpu (&o->iops_log_file, top->iops_log_file);
@@ -304,6 +306,12 @@ void convert_thread_options_to_cpu(struct thread_options *o,for (i =0 ; i <FIO_IO_U_LIST_MAX_LEN ; i++) o->percentile_list[i].u.f =fio_uint64_to_double (le64_to_cpu (top->percentile_list[i].u.i)); + +for (i =0 ; i <FIO_IO_U_LIST_MAX_LEN ; i++) + o->merge_blktrace_scalars[i].u.f =fio_uint64_to_double (le64_to_cpu (top->merge_blktrace_scalars[i].u.i)); + +for (i =0 ; i <FIO_IO_U_LIST_MAX_LEN ; i++) + o->merge_blktrace_iters[i].u.f =fio_uint64_to_double (le64_to_cpu (top->merge_blktrace_iters[i].u.i));#if 0 uint8_t cpumask[FIO_TOP_STR_MAX ];uint8_t verify_cpumask[FIO_TOP_STR_MAX ];
@@ -330,6 +338,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top,string_to_net (top->mmapfile, o->mmapfile);string_to_net (top->read_iolog_file, o->read_iolog_file);string_to_net (top->write_iolog_file, o->write_iolog_file); +string_to_net (top->merge_blktrace_file, o->merge_blktrace_file);string_to_net (top->bw_log_file, o->bw_log_file);string_to_net (top->lat_log_file, o->lat_log_file);string_to_net (top->iops_log_file, o->iops_log_file);
@@ -565,6 +574,12 @@ void convert_thread_options_to_net(struct thread_options_pack *top,for (i =0 ; i <FIO_IO_U_LIST_MAX_LEN ; i++) top->percentile_list[i].u.i =__cpu_to_le64 (fio_double_to_uint64 (o->percentile_list[i].u.f)); + +for (i =0 ; i <FIO_IO_U_LIST_MAX_LEN ; i++) + top->merge_blktrace_scalars[i].u.i =__cpu_to_le64 (fio_double_to_uint64 (o->merge_blktrace_scalars[i].u.f)); + +for (i =0 ; i <FIO_IO_U_LIST_MAX_LEN ; i++) + top->merge_blktrace_iters[i].u.i =__cpu_to_le64 (fio_double_to_uint64 (o->merge_blktrace_iters[i].u.f));#if 0 uint8_t cpumask[FIO_TOP_STR_MAX ];uint8_t verify_cpumask[FIO_TOP_STR_MAX ];
fio.1 +66 -0
84 lines not on this page · raw message
init.c +21 -0
@@ -30,6 +30,7 @@#include "idletime.h" #include "filelock.h" #include "steadystate.h" +#include "blktrace.h" #include "oslib/getopt.h" #include "oslib/strcasestr.h"
@@ -46,6 +47,7 @@ static char **ini_file;static int max_jobs =FIO_MAX_JOBS ;static int dump_cmdline;static int parse_only; +static int merge_blktrace_only;static struct thread_data def_thread;struct thread_data *threads =NULL ;
@@ -287,6 +289,11 @@ static struct option l_opts[FIO_NR_OPTIONS] = { .val = 'K', }, { + .name = (char *) "merge-blktrace-only", + .has_arg = no_argument, + .val = 'A' | FIO_CLIENT_FLAG, + }, + { .name = NULL, }, };
@@ -1724,6 +1731,14 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,if (td_steadystate_init (td)) goto err; +if (o->merge_blktrace_file && !merge_blktrace_iologs (td)) + goto err; + +if (merge_blktrace_only) { +put_job (td); +return 0 ; + } +/* * recurse add identical jobs, clear numjobs and stonewall options * as they don't apply to sub-jobs
@@ -2173,6 +2188,7 @@ static void usage(const char *name)printf (" --debug=options\tEnable debug logging. May be one/more of:\n" );show_debug_categories ();printf (" --parse-only\t\tParse options only, don't start any IO\n" ); +printf (" --merge-blktrace-only\tMerge blktraces only, don't start any IO\n" );printf (" --output\t\tWrite output to file\n" );printf (" --bandwidth-log\tGenerate aggregate bandwidth logs\n" );printf (" --minimal\t\tMinimal (terse) output\n" );
@@ -2889,6 +2905,11 @@ int parse_cmd_line(int argc, char *argv[], int client_type) } trigger_timeout /=1000000 ;break ; + +case 'A' : + did_arg = true; + merge_blktrace_only =1 ; +break ;case '?' :log_err ("%s: unrecognized option '%s'\n" , argv[0 ], argv[optind -1 ]);
options.c +38 -9
97 lines not on this page · raw message
options.h +2 -0
@@ -16,6 +16,8 @@ void add_opt_posval(const char *, const char *, const char *);void del_opt_posval (const char *,const char *);struct thread_data ;void fio_options_free (struct thread_data *); +char *get_next_str (char **ptr); +int get_max_str_idx (char *input);char *get_name_by_idx (char *input,int index);int set_name_idx (char *,size_t ,char *,int ,bool );
server.h +1 -1
@@ -48,7 +48,7 @@ struct fio_net_cmd_reply { };enum { -FIO_SERVER_VER =74 , +FIO_SERVER_VER =77 ,FIO_SERVER_MAX_FRAGMENT_PDU =1024 ,FIO_SERVER_MAX_CMD_MB =2048 ,
thread_options.h +6 -0
@@ -258,6 +258,9 @@ struct thread_options {char *read_iolog_file;bool read_iolog_chunked;char *write_iolog_file; +char *merge_blktrace_file; +fio_fp64_t merge_blktrace_scalars[FIO_IO_U_LIST_MAX_LEN ]; +fio_fp64_t merge_blktrace_iters[FIO_IO_U_LIST_MAX_LEN ];unsigned int write_bw_log;unsigned int write_lat_log;
@@ -540,6 +543,9 @@ struct thread_options_pack {uint8_t read_iolog_file[FIO_TOP_STR_MAX ];uint8_t write_iolog_file[FIO_TOP_STR_MAX ]; +uint8_t merge_blktrace_file[FIO_TOP_STR_MAX ]; +fio_fp64_t merge_blktrace_scalars[FIO_IO_U_LIST_MAX_LEN ]; +fio_fp64_t merge_blktrace_iters[FIO_IO_U_LIST_MAX_LEN ];uint32_t write_bw_log;uint32_t write_lat_log;