X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=options.c;h=de691eb32144ef0468341639ef5fc79aab0d441c;hp=2f38b4ae75edddd208d16b2624dac3cf40b4203a;hb=02af09886db695e5ea2b7fd2a632733955f3c03f;hpb=e2de69dac799a1eecac1b52085f908729591ef5a diff --git a/options.c b/options.c index 2f38b4ae..de691eb3 100644 --- a/options.c +++ b/options.c @@ -16,7 +16,7 @@ #include "lib/fls.h" #include "options.h" -static FLIST_HEAD(ext_opt_list); +#include "crc/crc32c.h" /* * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that. @@ -227,6 +227,30 @@ static int str_mem_cb(void *data, const char *mem) return 0; } +static int str_verify_cb(void *data, const char *mem) +{ + struct thread_data *td = data; + + if (td->o.verify != VERIFY_CRC32C_INTEL) + return 0; + + if (!crc32c_intel_works()) { + log_info("fio: System does not support hw accelerated crc32c. Falling back to sw crc32c.\n"); + td->o.verify = VERIFY_CRC32C; + } + + return 0; +} + +static int fio_clock_source_cb(void *data, const char *str) +{ + struct thread_data *td = data; + + fio_clock_source = td->o.clocksource; + fio_time_init(); + return 0; +} + static int str_lockmem_cb(void fio_unused *data, unsigned long *val) { mlock_size = *val; @@ -431,6 +455,22 @@ static int str_fst_cb(void *data, const char *str) return 0; } +#ifdef FIO_HAVE_SYNC_FILE_RANGE +static int str_sfr_cb(void *data, const char *str) +{ + struct thread_data *td = data; + char *nr = get_opt_postfix(str); + + td->sync_file_range_nr = 1; + if (nr) { + td->sync_file_range_nr = atoi(nr); + free(nr); + } + + return 0; +} +#endif + static int check_dir(struct thread_data *td, char *fname) { char file[PATH_MAX], *dir; @@ -670,6 +710,7 @@ static int str_gtod_reduce_cb(void *data, int *il) struct thread_data *td = data; int val = *il; + td->o.disable_lat = !!val; td->o.disable_clat = !!val; td->o.disable_slat = !!val; td->o.disable_bw = !!val; @@ -736,7 +777,7 @@ static int kb_base_verify(struct fio_option *o, void *data) /* * Map of job/command line options */ -static struct fio_option options[] = { +static struct fio_option options[FIO_MAX_OPTS] = { { .name = "description", .type = FIO_OPT_STR_STORE, @@ -1112,6 +1153,33 @@ static struct fio_option options[] = { .help = "Issue fdatasync for writes every given number of blocks", .def = "0", }, +#ifdef FIO_HAVE_SYNC_FILE_RANGE + { + .name = "sync_file_range", + .posval = { + { .ival = "wait_before", + .oval = SYNC_FILE_RANGE_WAIT_BEFORE, + .help = "SYNC_FILE_RANGE_WAIT_BEFORE", + .or = 1, + }, + { .ival = "write", + .oval = SYNC_FILE_RANGE_WRITE, + .help = "SYNC_FILE_RANGE_WRITE", + .or = 1, + }, + { + .ival = "wait_after", + .oval = SYNC_FILE_RANGE_WAIT_AFTER, + .help = "SYNC_FILE_RANGE_WAIT_AFTER", + .or = 1, + }, + }, + .type = FIO_OPT_STR_MULTI, + .cb = str_sfr_cb, + .off1 = td_var_offset(sync_file_range), + .help = "Use sync_file_range()", + }, +#endif { .name = "direct", .type = FIO_OPT_BOOL, @@ -1175,6 +1243,29 @@ static struct fio_option options[] = { .off1 = td_var_offset(ramp_time), .help = "Ramp up time before measuring performance", }, + { + .name = "clocksource", + .type = FIO_OPT_STR, + .cb = fio_clock_source_cb, + .off1 = td_var_offset(clocksource), + .help = "What type of timing source to use", + .posval = { + { .ival = "gettimeofday", + .oval = CS_GTOD, + .help = "Use gettimeofday(2) for timing", + }, + { .ival = "clock_gettime", + .oval = CS_CGETTIME, + .help = "Use clock_gettime(2) for timing", + }, +#ifdef ARCH_HAVE_CPU_CLOCK + { .ival = "cpu", + .oval = CS_CPUCLOCK, + .help = "Use CPU private clock", + }, +#endif + }, + }, { .name = "mem", .alias = "iomem", @@ -1225,6 +1316,7 @@ static struct fio_option options[] = { .type = FIO_OPT_STR, .off1 = td_var_offset(verify), .help = "Verify data written", + .cb = str_verify_cb, .def = "0", .posval = { { .ival = "0", @@ -1337,6 +1429,20 @@ static struct fio_option options[] = { .help = "Number of async verifier threads to use", .parent = "verify", }, + { + .name = "verify_backlog", + .type = FIO_OPT_STR_VAL, + .off1 = td_var_offset(verify_backlog), + .help = "Verify after this number of blocks are written", + .parent = "verify", + }, + { + .name = "verify_backlog_batch", + .type = FIO_OPT_INT, + .off1 = td_var_offset(verify_batch), + .help = "Verify this number of IO blocks", + .parent = "verify_backlog", + }, #ifdef FIO_HAVE_CPU_AFFINITY { .name = "verify_async_cpus", @@ -1686,6 +1792,14 @@ static struct fio_option options[] = { .cb = str_gtod_reduce_cb, .def = "0", }, + { + .name = "disable_lat", + .type = FIO_OPT_BOOL, + .off1 = td_var_offset(disable_lat), + .help = "Disable latency numbers", + .parent = "gtod_reduce", + .def = "0", + }, { .name = "disable_clat", .type = FIO_OPT_BOOL, @@ -1744,6 +1858,13 @@ static struct fio_option options[] = { .minval = 100, .maxval = 1000, }, + { + .name = "cgroup_nodelete", + .type = FIO_OPT_BOOL, + .off1 = td_var_offset(cgroup_nodelete), + .help = "Do not delete cgroups after job completion", + .def = "0", + }, { .name = "uid", .type = FIO_OPT_INT, @@ -1761,6 +1882,17 @@ static struct fio_option options[] = { }, }; +static void add_to_lopt(struct option *lopt, struct fio_option *o, + const char *name) +{ + lopt->name = (char *) name; + lopt->val = FIO_GETOPT_JOB; + if (o->type == FIO_OPT_STR_SET) + lopt->has_arg = no_argument; + else + lopt->has_arg = required_argument; +} + void fio_options_dup_and_init(struct option *long_options) { struct fio_option *o; @@ -1774,12 +1906,11 @@ void fio_options_dup_and_init(struct option *long_options) o = &options[0]; while (o->name) { - long_options[i].name = (char *) o->name; - long_options[i].val = FIO_GETOPT_JOB; - if (o->type == FIO_OPT_STR_SET) - long_options[i].has_arg = no_argument; - else - long_options[i].has_arg = required_argument; + add_to_lopt(&long_options[i], o, o->name); + if (o->alias) { + i++; + add_to_lopt(&long_options[i], o, o->alias); + } i++; o++; @@ -1941,7 +2072,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts) for (ret = 0, i = 0; i < num_opts; i++) { opts[i] = fio_keyword_replace(opts[i]); - ret |= parse_option(opts[i], options, &ext_opt_list, td); + ret |= parse_option(opts[i], options, td); } return ret; @@ -1949,7 +2080,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts) int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val) { - return parse_cmd_option(opt, val, options, &ext_opt_list, td); + return parse_cmd_option(opt, val, options, td); } void fio_fill_default_options(struct thread_data *td) @@ -1959,7 +2090,7 @@ void fio_fill_default_options(struct thread_data *td) int fio_show_option_help(const char *opt) { - return show_cmd_help(options, &ext_opt_list, opt); + return show_cmd_help(options, opt); } static void __options_mem(struct thread_data *td, int alloc) @@ -2013,23 +2144,70 @@ unsigned int fio_get_kb_base(void *data) return kb_base; } -void register_ext_option(struct ext_option *eopt) +int add_option(struct fio_option *o) +{ + struct fio_option *__o; + int opt_index = 0; + + __o = options; + while (__o->name) { + opt_index++; + __o++; + } + + memcpy(&options[opt_index], o, sizeof(*o)); + return 0; +} + +void invalidate_profile_options(const char *prof_name) +{ + struct fio_option *o; + + o = options; + while (o->name) { + if (o->prof_name && !strcmp(o->prof_name, prof_name)) { + o->type = FIO_OPT_INVALID; + o->prof_name = NULL; + } + o++; + } +} + +void add_opt_posval(const char *optname, const char *ival, const char *help) { - dprint(FD_PARSE, "register option '%s'\n", eopt->o.name); - option_init(&eopt->o); - flist_add_tail(&eopt->list, &ext_opt_list); + struct fio_option *o; + unsigned int i; + + o = find_option(options, optname); + if (!o) + return; + + for (i = 0; i < PARSE_MAX_VP; i++) { + if (o->posval[i].ival) + continue; + + o->posval[i].ival = ival; + o->posval[i].help = help; + break; + } } -void prune_profile_options(const char *prof_name) +void del_opt_posval(const char *optname, const char *ival) { - struct ext_option *eo; - struct flist_head *n, *tmp; + struct fio_option *o; + unsigned int i; - flist_for_each_safe(n, tmp, &ext_opt_list) { - eo = flist_entry(n, struct ext_option, list); - if (strcmp(eo->prof_name, prof_name)) + o = find_option(options, optname); + if (!o) + return; + + for (i = 0; i < PARSE_MAX_VP; i++) { + if (!o->posval[i].ival) + continue; + if (strcmp(o->posval[i].ival, ival)) continue; - flist_del(&eo->list); - free(eo); + + o->posval[i].ival = NULL; + o->posval[i].help = NULL; } }