From 79d16311c8d0c7188d73df77838fb1b4b6ff58db Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 4 Mar 2010 12:43:20 +0100 Subject: [PATCH] Add support for loadable profiles Split the only existing profile, tiobench, into this setup. Signed-off-by: Jens Axboe --- Makefile | 4 +- debug.h | 1 + fio.h | 4 +- flist.h | 2 + init.c | 110 ++++++++++++++++---------------------------- options.c | 8 +--- profile.c | 42 +++++++++++++++++ profile.h | 21 +++++++++ profiles.h | 10 ---- profiles/tiobench.c | 28 +++++++++++ 10 files changed, 139 insertions(+), 91 deletions(-) create mode 100644 profile.c create mode 100644 profile.h delete mode 100644 profiles.h create mode 100644 profiles/tiobench.c diff --git a/Makefile b/Makefile index ce63cfc8..ce2374b6 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ SCRIPTS = fio_generate_plots OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \ rbtree.o diskutil.o fifo.o blktrace.o smalloc.o filehash.o helpers.o \ - cgroup.o + cgroup.o profile.o OBJS += crc/crc7.o OBJS += crc/crc16.o @@ -32,6 +32,8 @@ OBJS += engines/net.o OBJS += engines/syslet-rw.o OBJS += engines/guasi.o +OBJS += profiles/tiobench.o + ifneq ($(findstring $(MAKEFLAGS),s),s) ifndef V QUIET_CC = @echo ' ' CC $@; diff --git a/debug.h b/debug.h index 1a2b79ab..71b346d8 100644 --- a/debug.h +++ b/debug.h @@ -16,6 +16,7 @@ enum { FD_DISKUTIL, FD_JOB, FD_MUTEX, + FD_PROFILE, FD_DEBUG_MAX, }; diff --git a/fio.h b/fio.h index bdc17081..7eb02ad4 100644 --- a/fio.h +++ b/fio.h @@ -28,7 +28,6 @@ #include "io_ddir.h" #include "ioengine.h" #include "iolog.h" -#include "profiles.h" #include "helpers.h" #ifdef FIO_HAVE_GUASI @@ -271,7 +270,7 @@ struct thread_options { /* * Benchmark profile type */ - unsigned int profile; + char *profile; /* * blkio cgroup support @@ -538,6 +537,7 @@ extern void fio_options_dup_and_init(struct option *); extern void options_mem_dupe(struct thread_data *); extern void options_mem_free(struct thread_data *); extern void td_fill_rand_seeds(struct thread_data *); +extern void add_job_opts(const char **); #define FIO_GETOPT_JOB 0x89988998 #define FIO_NR_OPTIONS 128 diff --git a/flist.h b/flist.h index 95023c75..7aca9730 100644 --- a/flist.h +++ b/flist.h @@ -1,6 +1,8 @@ #ifndef _LINUX_FLIST_H #define _LINUX_FLIST_H +#include + #undef offsetof #ifdef __compiler_offsetof #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) diff --git a/init.c b/init.c index 7785e9e4..c0ce4312 100644 --- a/init.c +++ b/init.c @@ -19,6 +19,7 @@ #include "smalloc.h" #include "filehash.h" #include "verify.h" +#include "profile.h" static char fio_version_string[] = "fio 1.37"; @@ -136,26 +137,6 @@ static struct option l_opts[FIO_NR_OPTIONS] = { }, }; -static const char *tiobench_opts[] = { - "buffered=0", "size=4*1024*$mb_memory", "bs=4k", "timeout=600", - "numjobs=4", "group_reporting", "thread", "overwrite=1", - "filename=.fio.tio.1:.fio.tio.2:.fio.tio.3:.fio.tio.4", - "name=seqwrite", "rw=write", "end_fsync=1", - "name=randwrite", "stonewall", "rw=randwrite", "end_fsync=1", - "name=seqread", "stonewall", "rw=read", - "name=randread", "stonewall", "rw=randread", NULL, -}; - -static const char **fio_prof_strings[PROFILE_END] = { - NULL, - tiobench_opts, -}; - -static const char *profiles[PROFILE_END] = { - "none", - "tiobench", -}; - FILE *get_f_out() { return f_out; @@ -655,6 +636,43 @@ err: return -1; } +/* + * Parse as if 'o' was a command line + */ +void add_job_opts(const char **o) +{ + struct thread_data *td, *td_parent; + int i, in_global = 1; + char jobname[32]; + + i = 0; + td_parent = td = NULL; + while (o[i]) { + if (!strncmp(o[i], "name", 4)) { + in_global = 0; + if (td) + add_job(td, jobname, 0); + td = NULL; + sprintf(jobname, "%s", o[i] + 5); + } + if (in_global && !td_parent) + td_parent = get_new_job(1, &def_thread); + else if (!in_global && !td) { + if (!td_parent) + td_parent = &def_thread; + td = get_new_job(0, td_parent); + } + if (in_global) + fio_options_parse(td_parent, (char **) &o[i], 1); + else + fio_options_parse(td, (char **) &o[i], 1); + i++; + } + + if (td) + add_job(td, jobname, 0); +} + static int skip_this_section(const char *name) { if (!job_section) @@ -961,6 +979,7 @@ struct debug_level debug_levels[] = { { .name = "diskutil", .shift = FD_DISKUTIL }, { .name = "job", .shift = FD_JOB }, { .name = "mutex", .shift = FD_MUTEX }, + { .name = "profile", .shift = FD_PROFILE }, { .name = NULL, }, }; @@ -1028,57 +1047,6 @@ static int set_debug(const char *string) } #endif -static int load_profile(const char *profile) -{ - struct thread_data *td, *td_parent; - const char **o; - int i, in_global = 1; - char jobname[32]; - - dprint(FD_PARSE, "loading profile '%s'\n", profile); - - for (i = 0; i < PROFILE_END; i++) { - if (!strcmp(profile, profiles[i])) - break; - } - - if (i == PROFILE_END) { - log_err("fio: unknown profile '%s'\n", profile); - return 1; - } - - o = fio_prof_strings[i]; - if (!o) - return 0; - - i = 0; - td_parent = td = NULL; - while (o[i]) { - if (!strncmp(o[i], "name", 4)) { - in_global = 0; - if (td) - add_job(td, jobname, 0); - td = NULL; - sprintf(jobname, "%s", o[i] + 5); - } - if (in_global && !td_parent) - td_parent = get_new_job(1, &def_thread); - else if (!in_global && !td) { - if (!td_parent) - td_parent = &def_thread; - td = get_new_job(0, td_parent); - } - if (in_global) - fio_options_parse(td_parent, (char **) &o[i], 1); - else - fio_options_parse(td, (char **) &o[i], 1); - i++; - } - if (td) - add_job(td, jobname, 0); - return 0; -} - static int parse_cmd_line(int argc, char *argv[]) { struct thread_data *td = NULL; diff --git a/options.c b/options.c index 0e57e52b..03b24377 100644 --- a/options.c +++ b/options.c @@ -1726,14 +1726,8 @@ static struct fio_option options[] = { }, { .name = "profile", - .type = FIO_OPT_STR, + .type = FIO_OPT_STR_STORE, .off1 = td_var_offset(profile), - .posval = { - { .ival = "tiobench", - .oval = PROFILE_TIOBENCH, - .help = "Perform tiobench like test", - }, - }, .help = "Select a specific builtin performance test", }, { diff --git a/profile.c b/profile.c new file mode 100644 index 00000000..e56ca29b --- /dev/null +++ b/profile.c @@ -0,0 +1,42 @@ +#include "fio.h" +#include "profile.h" +#include "debug.h" +#include "flist.h" + +static FLIST_HEAD(profile_list); + +int load_profile(const char *profile) +{ + struct profile_ops *ops; + struct flist_head *n; + + dprint(FD_PROFILE, "loading profile '%s'\n", profile); + + flist_for_each(n, &profile_list) { + ops = flist_entry(n, struct profile_ops, list); + if (!strcmp(profile, ops->name)) + break; + + ops = NULL; + } + + if (ops) { + add_job_opts(ops->def_ops); + return 0; + } + + log_err("fio: profile '%s' not found\n", profile); + return 1; +} + +void register_profile(struct profile_ops *ops) +{ + dprint(FD_PROFILE, "register profile '%s'\n", ops->name); + flist_add_tail(&ops->list, &profile_list); +} + +void unregister_profile(struct profile_ops *ops) +{ + dprint(FD_PROFILE, "unregister profile '%s'\n", ops->name); + flist_del(&ops->list); +} diff --git a/profile.h b/profile.h new file mode 100644 index 00000000..6b196062 --- /dev/null +++ b/profile.h @@ -0,0 +1,21 @@ +#ifndef FIO_PROFILE_H +#define FIO_PROFILE_H + +#include "flist.h" + +#define FIO_PROFILE_VERSION 1 + +struct profile_ops { + struct flist_head list; + char name[32]; + int version; + int flags; + + const char **def_ops; +}; + +void register_profile(struct profile_ops *); +void unregister_profile(struct profile_ops *); +int load_profile(const char *); + +#endif diff --git a/profiles.h b/profiles.h deleted file mode 100644 index 8203a464..00000000 --- a/profiles.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef FIO_PROFILE_H -#define FIO_PROFILE_H - -enum { - PROFILE_NONE = 0, - PROFILE_TIOBENCH = 1, - PROFILE_END = 2, -}; - -#endif diff --git a/profiles/tiobench.c b/profiles/tiobench.c new file mode 100644 index 00000000..d239468f --- /dev/null +++ b/profiles/tiobench.c @@ -0,0 +1,28 @@ +#include "../fio.h" +#include "../profile.h" + +static const char *tb_opts[] = { + "buffered=0", "size=4*1024*$mb_memory", "bs=4k", "timeout=600", + "numjobs=4", "group_reporting", "thread", "overwrite=1", + "filename=.fio.tio.1:.fio.tio.2:.fio.tio.3:.fio.tio.4", + "name=seqwrite", "rw=write", "end_fsync=1", + "name=randwrite", "stonewall", "rw=randwrite", "end_fsync=1", + "name=seqread", "stonewall", "rw=read", + "name=randread", "stonewall", "rw=randread", NULL, +}; + +static struct profile_ops tiobench_profile = { + .name = "tiobench", + .version = FIO_PROFILE_VERSION, + .def_ops = tb_opts, +}; + +static void fio_init tiobench_register(void) +{ + register_profile(&tiobench_profile); +} + +static void fio_exit tiobench_unregister(void) +{ + unregister_profile(&tiobench_profile); +} -- 2.25.1