X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=options.c;h=61ea41cc4e0fc673893c3b9ecc9ec647c4216e3a;hp=91049af5472e55abecf65a266aa28b2162ea1d15;hb=refs%2Fheads%2Fmaster;hpb=5f81856714671287e93e087af8943d3d1779dd5f diff --git a/options.c b/options.c index 91049af5..61ea41cc 100644 --- a/options.c +++ b/options.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -269,12 +270,19 @@ static int str_fdp_pli_cb(void *data, const char *input) strip_blank_front(&str); strip_blank_end(str); - while ((v = strsep(&str, ",")) != NULL && i < FIO_MAX_PLIS) - td->o.fdp_plis[i++] = strtoll(v, NULL, 0); + while ((v = strsep(&str, ",")) != NULL && i < FIO_MAX_DP_IDS) { + unsigned long long id = strtoull(v, NULL, 0); + if (id > 0xFFFF) { + log_err("Placement IDs cannot exceed 0xFFFF\n"); + free(p); + return 1; + } + td->o.dp_ids[i++] = id; + } free(p); - qsort(td->o.fdp_plis, i, sizeof(*td->o.fdp_plis), fio_fdp_cmp); - td->o.fdp_nrpli = i; + qsort(td->o.dp_ids, i, sizeof(*td->o.dp_ids), fio_fdp_cmp); + td->o.dp_nr_ids = i; return 0; } @@ -312,15 +320,17 @@ static int parse_cmdprio_bssplit_entry(struct thread_options *o, int matches = 0; char *bs_str = NULL; long long bs_val; - unsigned int perc = 0, class, level; + unsigned int perc = 0, class, level, hint; /* * valid entry formats: * bs/ - %s/ - set perc to 0, prio to -1. * bs/perc - %s/%u - set prio to -1. * bs/perc/class/level - %s/%u/%u/%u + * bs/perc/class/level/hint - %s/%u/%u/%u/%u */ - matches = sscanf(str, "%m[^/]/%u/%u/%u", &bs_str, &perc, &class, &level); + matches = sscanf(str, "%m[^/]/%u/%u/%u/%u", + &bs_str, &perc, &class, &level, &hint); if (matches < 1) { log_err("fio: invalid cmdprio_bssplit format\n"); return 1; @@ -341,9 +351,14 @@ static int parse_cmdprio_bssplit_entry(struct thread_options *o, case 2: /* bs/perc case */ break; case 4: /* bs/perc/class/level case */ + case 5: /* bs/perc/class/level/hint case */ class = min(class, (unsigned int) IOPRIO_MAX_PRIO_CLASS); level = min(level, (unsigned int) IOPRIO_MAX_PRIO); - entry->prio = ioprio_value(class, level); + if (matches == 5) + hint = min(hint, (unsigned int) IOPRIO_MAX_PRIO_HINT); + else + hint = 0; + entry->prio = ioprio_value(class, level, hint); break; default: log_err("fio: invalid cmdprio_bssplit format\n"); @@ -588,9 +603,21 @@ static int str_rw_cb(void *data, const char *str) if (!nr) return 0; - if (td_random(td)) - o->ddir_seq_nr = atoi(nr); - else { + if (td_random(td)) { + long long val; + + if (str_to_decimal(nr, &val, 1, o, 0, 0)) { + log_err("fio: randrw postfix parsing failed\n"); + free(nr); + return 1; + } + if ((val <= 0) || (val > UINT_MAX)) { + log_err("fio: randrw postfix parsing out of range\n"); + free(nr); + return 1; + } + o->ddir_seq_nr = (unsigned int) val; + } else { long long val; if (str_to_decimal(nr, &val, 1, o, 0, 0)) { @@ -627,7 +654,7 @@ static int fio_clock_source_cb(void *data, const char *str) return 0; } -static int str_rwmix_read_cb(void *data, unsigned long long *val) +static int str_rwmix_read_cb(void *data, long long *val) { struct thread_data *td = cb_data_to_td(data); @@ -636,7 +663,7 @@ static int str_rwmix_read_cb(void *data, unsigned long long *val) return 0; } -static int str_rwmix_write_cb(void *data, unsigned long long *val) +static int str_rwmix_write_cb(void *data, long long *val) { struct thread_data *td = cb_data_to_td(data); @@ -1605,7 +1632,7 @@ static int str_gtod_reduce_cb(void *data, int *il) return 0; } -static int str_offset_cb(void *data, unsigned long long *__val) +static int str_offset_cb(void *data, long long *__val) { struct thread_data *td = cb_data_to_td(data); unsigned long long v = *__val; @@ -1626,7 +1653,7 @@ static int str_offset_cb(void *data, unsigned long long *__val) return 0; } -static int str_offset_increment_cb(void *data, unsigned long long *__val) +static int str_offset_increment_cb(void *data, long long *__val) { struct thread_data *td = cb_data_to_td(data); unsigned long long v = *__val; @@ -1647,7 +1674,7 @@ static int str_offset_increment_cb(void *data, unsigned long long *__val) return 0; } -static int str_size_cb(void *data, unsigned long long *__val) +static int str_size_cb(void *data, long long *__val) { struct thread_data *td = cb_data_to_td(data); unsigned long long v = *__val; @@ -1691,7 +1718,7 @@ static int str_io_size_cb(void *data, unsigned long long *__val) return 0; } -static int str_zoneskip_cb(void *data, unsigned long long *__val) +static int str_zoneskip_cb(void *data, long long *__val) { struct thread_data *td = cb_data_to_td(data); unsigned long long v = *__val; @@ -2375,6 +2402,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_INVALID, }, + { + .name = "num_range", + .lname = "Number of ranges", + .type = FIO_OPT_INT, + .off1 = offsetof(struct thread_options, num_range), + .maxval = MAX_TRIM_RANGE, + .help = "Number of ranges for trim command", + .def = "1", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_INVALID, + }, { .name = "bs", .lname = "Block size", @@ -2464,6 +2502,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { }, { .name = "randrepeat", + .alias = "allrandrepeat", .lname = "Random repeatable", .type = FIO_OPT_BOOL, .off1 = offsetof(struct thread_options, rand_repeatable), @@ -2593,16 +2632,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_RANDOM, }, - { - .name = "allrandrepeat", - .lname = "All Random Repeat", - .type = FIO_OPT_BOOL, - .off1 = offsetof(struct thread_options, allrand_repeatable), - .help = "Use repeatable random numbers for everything", - .def = "0", - .category = FIO_OPT_C_IO, - .group = FIO_OPT_G_RANDOM, - }, { .name = "nrfiles", .lname = "Number of files", @@ -2740,6 +2769,12 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .oval = F_ADV_SEQUENTIAL, .help = "Advise using FADV_SEQUENTIAL", }, +#ifdef POSIX_FADV_NOREUSE + { .ival = "noreuse", + .oval = F_ADV_NOREUSE, + .help = "Advise using FADV_NOREUSE", + }, +#endif }, .help = "Use fadvise() to advise the kernel on IO pattern", .def = "1", @@ -3620,7 +3655,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .lname = "Per device/file maximum number of open zones", .type = FIO_OPT_INT, .off1 = offsetof(struct thread_options, max_open_zones), - .maxval = ZBD_MAX_OPEN_ZONES, + .maxval = ZBD_MAX_WRITE_ZONES, .help = "Limit on the number of simultaneously opened sequential write zones with zonemode=zbd", .def = "0", .category = FIO_OPT_C_IO, @@ -3631,7 +3666,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .lname = "Job maximum number of open zones", .type = FIO_OPT_INT, .off1 = offsetof(struct thread_options, job_max_open_zones), - .maxval = ZBD_MAX_OPEN_ZONES, + .maxval = ZBD_MAX_WRITE_ZONES, .help = "Limit on the number of simultaneously opened sequential write zones with zonemode=zbd by one thread/process", .def = "0", .category = FIO_OPT_C_IO, @@ -3682,12 +3717,59 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .group = FIO_OPT_G_INVALID, }, { - .name = "fdp_pli", - .lname = "FDP Placement ID indicies", + .name = "dataplacement", + .alias = "data_placement", + .lname = "Data Placement interface", + .type = FIO_OPT_STR, + .off1 = offsetof(struct thread_options, dp_type), + .help = "Data Placement interface to use", + .def = "none", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_INVALID, + .posval = { + { .ival = "none", + .oval = FIO_DP_NONE, + .help = "Do not specify a data placement interface", + }, + { .ival = "fdp", + .oval = FIO_DP_FDP, + .help = "Use Flexible Data Placement interface", + }, + { .ival = "streams", + .oval = FIO_DP_STREAMS, + .help = "Use Streams interface", + }, + }, + }, + { + .name = "plid_select", + .alias = "fdp_pli_select", + .lname = "Data Placement ID selection strategy", + .type = FIO_OPT_STR, + .off1 = offsetof(struct thread_options, dp_id_select), + .help = "Strategy for selecting next Data Placement ID", + .def = "roundrobin", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_INVALID, + .posval = { + { .ival = "random", + .oval = FIO_DP_RANDOM, + .help = "Choose a Placement ID at random (uniform)", + }, + { .ival = "roundrobin", + .oval = FIO_DP_RR, + .help = "Round robin select Placement IDs", + }, + }, + }, + { + .name = "plids", + .alias = "fdp_pli", + .lname = "Stream IDs/Data Placement ID indices", .type = FIO_OPT_STR, .cb = str_fdp_pli_cb, - .off1 = offsetof(struct thread_options, fdp_plis), - .help = "Sets which placement ids to use (defaults to all)", + .off1 = offsetof(struct thread_options, dp_ids), + .help = "Sets which Data Placement ids to use (defaults to all for FDP)", .hide = 1, .category = FIO_OPT_C_IO, .group = FIO_OPT_G_INVALID, @@ -3788,6 +3870,18 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_GENERAL, .group = FIO_OPT_G_CRED, }, + { + .name = "priohint", + .lname = "I/O nice priority hint", + .type = FIO_OPT_INT, + .off1 = offsetof(struct thread_options, ioprio_hint), + .help = "Set job IO priority hint", + .minval = IOPRIO_MIN_PRIO_HINT, + .maxval = IOPRIO_MAX_PRIO_HINT, + .interval = 1, + .category = FIO_OPT_C_GENERAL, + .group = FIO_OPT_G_CRED, + }, #else { .name = "prioclass", @@ -3795,6 +3889,12 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .type = FIO_OPT_UNSUPPORTED, .help = "Your platform does not support IO priority classes", }, + { + .name = "priohint", + .lname = "I/O nice priority hint", + .type = FIO_OPT_UNSUPPORTED, + .help = "Your platform does not support IO priority hints", + }, #endif { .name = "thinktime", @@ -3820,6 +3920,18 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_THINKTIME, }, + { + .name = "thinkcycles", + .lname = "Think cycles", + .type = FIO_OPT_INT, + .off1 = offsetof(struct thread_options, thinkcycles), + .help = "Spin for a constant amount of cycles between requests", + .def = "0", + .parent = "thinktime", + .hide = 1, + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_THINKTIME, + }, { .name = "thinktime_blocks", .lname = "Thinktime blocks", @@ -4473,14 +4585,38 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .group = FIO_OPT_G_INVALID, }, { - .name = "log_max_value", - .lname = "Log maximum instead of average", - .type = FIO_OPT_BOOL, + .name = "log_window_value", + .alias = "log_max_value", + .lname = "Log maximum, average or both values", + .type = FIO_OPT_STR, .off1 = offsetof(struct thread_options, log_max), - .help = "Log max sample in a window instead of average", - .def = "0", + .help = "Log max, average or both sample in a window", + .def = "avg", .category = FIO_OPT_C_LOG, .group = FIO_OPT_G_INVALID, + .posval = { + { .ival = "avg", + .oval = IO_LOG_SAMPLE_AVG, + .help = "Log average value over the window", + }, + { .ival = "max", + .oval = IO_LOG_SAMPLE_MAX, + .help = "Log maximum value in the window", + }, + { .ival = "both", + .oval = IO_LOG_SAMPLE_BOTH, + .help = "Log both average and maximum values over the window" + }, + /* Compatibility with former boolean values */ + { .ival = "0", + .oval = IO_LOG_SAMPLE_AVG, + .help = "Alias for 'avg'", + }, + { .ival = "1", + .oval = IO_LOG_SAMPLE_MAX, + .help = "Alias for 'max'", + }, + }, }, { .name = "log_offset", @@ -4557,17 +4693,9 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .help = "Install libz-dev(el) to get compression support", }, #endif - { - .name = "log_unix_epoch", - .lname = "Log epoch unix", - .type = FIO_OPT_BOOL, - .off1 = offsetof(struct thread_options, log_unix_epoch), - .help = "Use Unix time in log files", - .category = FIO_OPT_C_LOG, - .group = FIO_OPT_G_INVALID, - }, { .name = "log_alternate_epoch", + .alias = "log_unix_epoch", .lname = "Log epoch alternate", .type = FIO_OPT_BOOL, .off1 = offsetof(struct thread_options, log_alternate_epoch), @@ -4580,7 +4708,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .lname = "Log alternate epoch clock_id", .type = FIO_OPT_INT, .off1 = offsetof(struct thread_options, log_alternate_epoch_clock_id), - .help = "If log_alternate_epoch or log_unix_epoch is true, this option specifies the clock_id from clock_gettime whose epoch should be used. If neither of those is true, this option has no effect. Default value is 0, or CLOCK_REALTIME", + .help = "If log_alternate_epoch is true, this option specifies the clock_id from clock_gettime whose epoch should be used. If log_alternate_epoch is false, this option has no effect. Default value is 0, or CLOCK_REALTIME", .category = FIO_OPT_C_LOG, .group = FIO_OPT_G_INVALID, }, @@ -4909,6 +5037,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_GENERAL, .group = FIO_OPT_G_CLOCK, }, + { + .name = "job_start_clock_id", + .lname = "Job start clock_id", + .type = FIO_OPT_INT, + .off1 = offsetof(struct thread_options, job_start_clock_id), + .help = "The clock_id passed to the call to clock_gettime used to record job_start in the json output format. Default is 0, or CLOCK_REALTIME", + .verify = gtod_cpu_verify, + .category = FIO_OPT_C_GENERAL, + .group = FIO_OPT_G_CLOCK, + }, { .name = "unified_rw_reporting", .lname = "Unified RW Reporting", @@ -5228,6 +5366,20 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_GENERAL, .group = FIO_OPT_G_RUNTIME, }, + { + .name = "steadystate_check_interval", + .lname = "Steady state check interval", + .alias = "ss_interval", + .parent = "steadystate", + .type = FIO_OPT_STR_VAL_TIME, + .off1 = offsetof(struct thread_options, ss_check_interval), + .help = "Polling interval for the steady state check (too low means steadystate will not converge)", + .def = "1", + .is_seconds = 1, + .is_time = 1, + .category = FIO_OPT_C_GENERAL, + .group = FIO_OPT_G_RUNTIME, + }, { .name = NULL, },