X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=options.c;h=681052127be67b2db7fbaa6d1bf927f7fdbb0342;hp=4bea8f781304312bc35a746df487210f53bb38c8;hb=c712c97ab8714165216c5940b4a540bd42fdbd68;hpb=f27300d51e3291c2588b3534c7236b2a102351ff diff --git a/options.c b/options.c index 4bea8f78..68105212 100644 --- a/options.c +++ b/options.c @@ -56,14 +56,16 @@ static int bs_cmp(const void *p1, const void *p2) struct split { unsigned int nr; - unsigned int val1[100]; - unsigned int val2[100]; + unsigned int val1[ZONESPLIT_MAX]; + unsigned long long val2[ZONESPLIT_MAX]; }; static int split_parse_ddir(struct thread_options *o, struct split *split, - enum fio_ddir ddir, char *str) + enum fio_ddir ddir, char *str, bool absolute, + unsigned int max_splits) { - unsigned int i, perc; + unsigned long long perc; + unsigned int i; long long val; char *fname; @@ -80,31 +82,46 @@ static int split_parse_ddir(struct thread_options *o, struct split *split, if (perc_str) { *perc_str = '\0'; perc_str++; - perc = atoi(perc_str); - if (perc > 100) - perc = 100; - else if (!perc) + if (absolute) { + if (str_to_decimal(perc_str, &val, 1, o, 0, 0)) { + log_err("fio: split conversion failed\n"); + return 1; + } + perc = val; + } else { + perc = atoi(perc_str); + if (perc > 100) + perc = 100; + else if (!perc) + perc = -1U; + } + } else { + if (absolute) + perc = 0; + else perc = -1U; - } else - perc = -1U; + } if (str_to_decimal(fname, &val, 1, o, 0, 0)) { - log_err("fio: bssplit conversion failed\n"); + log_err("fio: split conversion failed\n"); return 1; } split->val1[i] = val; split->val2[i] = perc; i++; - if (i == 100) + if (i == max_splits) { + log_err("fio: hit max of %d split entries\n", i); break; + } } split->nr = i; return 0; } -static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str) +static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str, + bool data) { unsigned int i, perc, perc_missing; unsigned int max_bs, min_bs; @@ -112,7 +129,7 @@ static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str) memset(&split, 0, sizeof(split)); - if (split_parse_ddir(o, &split, ddir, str)) + if (split_parse_ddir(o, &split, ddir, str, data, BSSPLIT_MAX)) return 1; if (!split.nr) return 0; @@ -176,9 +193,10 @@ static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str) return 0; } -typedef int (split_parse_fn)(struct thread_options *, enum fio_ddir, char *); +typedef int (split_parse_fn)(struct thread_options *, enum fio_ddir, char *, bool); -static int str_split_parse(struct thread_data *td, char *str, split_parse_fn *fn) +static int str_split_parse(struct thread_data *td, char *str, + split_parse_fn *fn, bool data) { char *odir, *ddir; int ret = 0; @@ -187,37 +205,37 @@ static int str_split_parse(struct thread_data *td, char *str, split_parse_fn *fn if (odir) { ddir = strchr(odir + 1, ','); if (ddir) { - ret = fn(&td->o, DDIR_TRIM, ddir + 1); + ret = fn(&td->o, DDIR_TRIM, ddir + 1, data); if (!ret) *ddir = '\0'; } else { char *op; op = strdup(odir + 1); - ret = fn(&td->o, DDIR_TRIM, op); + ret = fn(&td->o, DDIR_TRIM, op, data); free(op); } if (!ret) - ret = fn(&td->o, DDIR_WRITE, odir + 1); + ret = fn(&td->o, DDIR_WRITE, odir + 1, data); if (!ret) { *odir = '\0'; - ret = fn(&td->o, DDIR_READ, str); + ret = fn(&td->o, DDIR_READ, str, data); } } else { char *op; op = strdup(str); - ret = fn(&td->o, DDIR_WRITE, op); + ret = fn(&td->o, DDIR_WRITE, op, data); free(op); if (!ret) { op = strdup(str); - ret = fn(&td->o, DDIR_TRIM, op); + ret = fn(&td->o, DDIR_TRIM, op, data); free(op); } if (!ret) - ret = fn(&td->o, DDIR_READ, str); + ret = fn(&td->o, DDIR_READ, str, data); } return ret; @@ -234,7 +252,7 @@ static int str_bssplit_cb(void *data, const char *input) strip_blank_front(&str); strip_blank_end(str); - ret = str_split_parse(td, str, bssplit_ddir); + ret = str_split_parse(td, str, bssplit_ddir, false); if (parse_dryrun()) { int i; @@ -824,14 +842,14 @@ static int str_sfr_cb(void *data, const char *str) #endif static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, - char *str) + char *str, bool absolute) { unsigned int i, perc, perc_missing, sperc, sperc_missing; struct split split; memset(&split, 0, sizeof(split)); - if (split_parse_ddir(o, &split, ddir, str)) + if (split_parse_ddir(o, &split, ddir, str, absolute, ZONESPLIT_MAX)) return 1; if (!split.nr) return 0; @@ -840,7 +858,10 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, o->zone_split_nr[ddir] = split.nr; for (i = 0; i < split.nr; i++) { o->zone_split[ddir][i].access_perc = split.val1[i]; - o->zone_split[ddir][i].size_perc = split.val2[i]; + if (absolute) + o->zone_split[ddir][i].size = split.val2[i]; + else + o->zone_split[ddir][i].size_perc = split.val2[i]; } /* @@ -856,11 +877,12 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, else perc += zsp->access_perc; - if (zsp->size_perc == (uint8_t) -1U) - sperc_missing++; - else - sperc += zsp->size_perc; - + if (!absolute) { + if (zsp->size_perc == (uint8_t) -1U) + sperc_missing++; + else + sperc += zsp->size_perc; + } } if (perc > 100 || sperc > 100) { @@ -908,10 +930,11 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, static void __td_zone_gen_index(struct thread_data *td, enum fio_ddir ddir) { unsigned int i, j, sprev, aprev; + uint64_t sprev_sz; td->zone_state_index[ddir] = malloc(sizeof(struct zone_split_index) * 100); - sprev = aprev = 0; + sprev_sz = sprev = aprev = 0; for (i = 0; i < td->o.zone_split_nr[ddir]; i++) { struct zone_split *zsp = &td->o.zone_split[ddir][i]; @@ -920,10 +943,14 @@ static void __td_zone_gen_index(struct thread_data *td, enum fio_ddir ddir) zsi->size_perc = sprev + zsp->size_perc; zsi->size_perc_prev = sprev; + + zsi->size = sprev_sz + zsp->size; + zsi->size_prev = sprev_sz; } aprev += zsp->access_perc; sprev += zsp->size_perc; + sprev_sz += zsp->size; } } @@ -942,8 +969,10 @@ static void td_zone_gen_index(struct thread_data *td) __td_zone_gen_index(td, i); } -static int parse_zoned_distribution(struct thread_data *td, const char *input) +static int parse_zoned_distribution(struct thread_data *td, const char *input, + bool absolute) { + const char *pre = absolute ? "zoned_abs:" : "zoned:"; char *str, *p; int i, ret = 0; @@ -953,14 +982,14 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input) strip_blank_end(str); /* We expect it to start like that, bail if not */ - if (strncmp(str, "zoned:", 6)) { + if (strncmp(str, pre, strlen(pre))) { log_err("fio: mismatch in zoned input <%s>\n", str); free(p); return 1; } - str += strlen("zoned:"); + str += strlen(pre); - ret = str_split_parse(td, str, zone_split_ddir); + ret = str_split_parse(td, str, zone_split_ddir, absolute); free(p); @@ -972,8 +1001,15 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input) for (j = 0; j < td->o.zone_split_nr[i]; j++) { struct zone_split *zsp = &td->o.zone_split[i][j]; - dprint(FD_PARSE, "\t%d: %u/%u\n", j, zsp->access_perc, - zsp->size_perc); + if (absolute) { + dprint(FD_PARSE, "\t%d: %u/%llu\n", j, + zsp->access_perc, + (unsigned long long) zsp->size); + } else { + dprint(FD_PARSE, "\t%d: %u/%u\n", j, + zsp->access_perc, + zsp->size_perc); + } } } @@ -1012,7 +1048,9 @@ static int str_random_distribution_cb(void *data, const char *str) else if (td->o.random_distribution == FIO_RAND_DIST_GAUSS) val = 0.0; else if (td->o.random_distribution == FIO_RAND_DIST_ZONED) - return parse_zoned_distribution(td, str); + return parse_zoned_distribution(td, str, false); + else if (td->o.random_distribution == FIO_RAND_DIST_ZONED_ABS) + return parse_zoned_distribution(td, str, true); else return 0; @@ -1092,9 +1130,9 @@ static int str_steadystate_cb(void *data, const char *str) if (parse_dryrun()) return 0; - td->o.ss_state |= __FIO_SS_PCT; + td->o.ss_state |= FIO_SS_PCT; td->o.ss_limit.u.f = val; - } else if (td->o.ss_state & __FIO_SS_IOPS) { + } else if (td->o.ss_state & FIO_SS_IOPS) { if (!str_to_float(nr, &val, 0)) { log_err("fio: steadystate IOPS threshold postfix parsing failed\n"); free(nr); @@ -2241,7 +2279,10 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .oval = FIO_RAND_DIST_ZONED, .help = "Zoned random distribution", }, - + { .ival = "zoned_abs", + .oval = FIO_RAND_DIST_ZONED_ABS, + .help = "Zoned absolute random distribution", + }, }, .category = FIO_OPT_C_IO, .group = FIO_OPT_G_RANDOM, @@ -2402,7 +2443,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .posval = { { .ival = "0", .oval = F_ADV_NONE, - .help = "Don't issue fadvise", + .help = "Don't issue fadvise/madvise", }, { .ival = "1", .oval = F_ADV_TYPE, @@ -3418,10 +3459,20 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_RATE, }, + { + .name = "rate_ignore_thinktime", + .lname = "Rate ignore thinktime", + .type = FIO_OPT_BOOL, + .off1 = offsetof(struct thread_options, rate_ign_think), + .help = "Rated IO ignores thinktime settings", + .parent = "rate", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_RATE, + }, { .name = "max_latency", - .lname = "Max Latency", - .type = FIO_OPT_INT, + .lname = "Max Latency (usec)", + .type = FIO_OPT_STR_VAL_TIME, .off1 = offsetof(struct thread_options, max_latency), .help = "Maximum tolerated IO latency (usec)", .is_time = 1,