fio: Introduce the log_prio option
[fio.git] / options.c
index e3b0c4effe9c2e38bf94ebe62b94d156fb8913c0..74ac1f3f6f2d13d1539a157dc22d693ed3141fb8 100644 (file)
--- a/options.c
+++ b/options.c
@@ -73,13 +73,7 @@ static int bs_cmp(const void *p1, const void *p2)
        return (int) bsp1->perc - (int) bsp2->perc;
 }
 
-struct split {
-       unsigned int nr;
-       unsigned long long val1[ZONESPLIT_MAX];
-       unsigned long long val2[ZONESPLIT_MAX];
-};
-
-static int split_parse_ddir(struct thread_options *o, struct split *split,
+int split_parse_ddir(struct thread_options *o, struct split *split,
                            char *str, bool absolute, unsigned int max_splits)
 {
        unsigned long long perc;
@@ -138,8 +132,8 @@ static int split_parse_ddir(struct thread_options *o, struct split *split,
        return 0;
 }
 
-static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str,
-                       bool data)
+static int bssplit_ddir(struct thread_options *o, void *eo,
+                       enum fio_ddir ddir, char *str, bool data)
 {
        unsigned int i, perc, perc_missing;
        unsigned long long max_bs, min_bs;
@@ -211,10 +205,8 @@ 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 *, bool);
-
-static int str_split_parse(struct thread_data *td, char *str,
-                          split_parse_fn *fn, bool data)
+int str_split_parse(struct thread_data *td, char *str,
+                   split_parse_fn *fn, void *eo, bool data)
 {
        char *odir, *ddir;
        int ret = 0;
@@ -223,37 +215,37 @@ static int str_split_parse(struct thread_data *td, char *str,
        if (odir) {
                ddir = strchr(odir + 1, ',');
                if (ddir) {
-                       ret = fn(&td->o, DDIR_TRIM, ddir + 1, data);
+                       ret = fn(&td->o, eo, DDIR_TRIM, ddir + 1, data);
                        if (!ret)
                                *ddir = '\0';
                } else {
                        char *op;
 
                        op = strdup(odir + 1);
-                       ret = fn(&td->o, DDIR_TRIM, op, data);
+                       ret = fn(&td->o, eo, DDIR_TRIM, op, data);
 
                        free(op);
                }
                if (!ret)
-                       ret = fn(&td->o, DDIR_WRITE, odir + 1, data);
+                       ret = fn(&td->o, eo, DDIR_WRITE, odir + 1, data);
                if (!ret) {
                        *odir = '\0';
-                       ret = fn(&td->o, DDIR_READ, str, data);
+                       ret = fn(&td->o, eo, DDIR_READ, str, data);
                }
        } else {
                char *op;
 
                op = strdup(str);
-               ret = fn(&td->o, DDIR_WRITE, op, data);
+               ret = fn(&td->o, eo, DDIR_WRITE, op, data);
                free(op);
 
                if (!ret) {
                        op = strdup(str);
-                       ret = fn(&td->o, DDIR_TRIM, op, data);
+                       ret = fn(&td->o, eo, DDIR_TRIM, op, data);
                        free(op);
                }
                if (!ret)
-                       ret = fn(&td->o, DDIR_READ, str, data);
+                       ret = fn(&td->o, eo, DDIR_READ, str, data);
        }
 
        return ret;
@@ -270,7 +262,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, false);
+       ret = str_split_parse(td, str, bssplit_ddir, NULL, false);
 
        if (parse_dryrun()) {
                int i;
@@ -906,8 +898,8 @@ 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, bool absolute)
+static int zone_split_ddir(struct thread_options *o, void *eo,
+                          enum fio_ddir ddir, char *str, bool absolute)
 {
        unsigned int i, perc, perc_missing, sperc, sperc_missing;
        struct split split;
@@ -1012,7 +1004,7 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input,
        }
        str += strlen(pre);
 
-       ret = str_split_parse(td, str, zone_split_ddir, absolute);
+       ret = str_split_parse(td, str, zone_split_ddir, NULL, absolute);
 
        free(p);
 
@@ -1945,6 +1937,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                            .help = "RDMA IO engine",
                          },
 #endif
+#ifdef CONFIG_LIBRPMA_APM
+                         { .ival = "librpma_apm",
+                           .help = "librpma IO engine in APM mode",
+                         },
+#endif
+#ifdef CONFIG_LIBRPMA_GPSPM
+                         { .ival = "librpma_gpspm",
+                           .help = "librpma IO engine in GPSPM mode",
+                         },
+#endif
 #ifdef CONFIG_LINUX_EXT4_MOVE_EXTENT
                          { .ival = "e4defrag",
                            .help = "ext4 defrag engine",
@@ -2011,6 +2013,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                          { .ival = "nbd",
                            .help = "Network Block Device (NBD) IO engine"
                          },
+#ifdef CONFIG_DFS
+                         { .ival = "dfs",
+                           .help = "DAOS File System (dfs) IO engine",
+                         },
+#endif
+#ifdef CONFIG_NFS
+                         { .ival = "nfs",
+                           .help = "NFS IO engine",
+                         },
+#endif
                },
        },
        {
@@ -3472,6 +3484,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_INVALID,
        },
+       {
+               .name   = "ignore_zone_limits",
+               .lname  = "Ignore zone resource limits",
+               .type   = FIO_OPT_BOOL,
+               .off1   = offsetof(struct thread_options, ignore_zone_limits),
+               .def    = "0",
+               .help   = "Ignore the zone resource limits (max open/active zones) reported by the device",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_INVALID,
+       },
        {
                .name   = "zone_reset_threshold",
                .lname  = "Zone reset threshold",
@@ -3756,8 +3778,10 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        {
                .name   = "max_latency",
                .lname  = "Max Latency (usec)",
-               .type   = FIO_OPT_STR_VAL_TIME,
-               .off1   = offsetof(struct thread_options, max_latency),
+               .type   = FIO_OPT_ULL,
+               .off1   = offsetof(struct thread_options, max_latency[DDIR_READ]),
+               .off2   = offsetof(struct thread_options, max_latency[DDIR_WRITE]),
+               .off3   = offsetof(struct thread_options, max_latency[DDIR_TRIM]),
                .help   = "Maximum tolerated IO latency (usec)",
                .is_time = 1,
                .category = FIO_OPT_C_IO,
@@ -4268,6 +4292,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_LOG,
                .group  = FIO_OPT_G_INVALID,
        },
+       {
+               .name   = "log_prio",
+               .lname  = "Log priority of IO",
+               .type   = FIO_OPT_BOOL,
+               .off1   = offsetof(struct thread_options, log_prio),
+               .help   = "Include priority value of IO for each log entry",
+               .def    = "0",
+               .category = FIO_OPT_C_LOG,
+               .group  = FIO_OPT_G_INVALID,
+       },
 #ifdef CONFIG_ZLIB
        {
                .name   = "log_compression",
@@ -4465,6 +4499,40 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IO_BUF,
        },
+       {
+               .name   = "dedupe_mode",
+               .lname  = "Dedupe mode",
+               .help   = "Mode for the deduplication buffer generation",
+               .type   = FIO_OPT_STR,
+               .off1   = offsetof(struct thread_options, dedupe_mode),
+               .parent = "dedupe_percentage",
+               .def    = "repeat",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IO_BUF,
+               .posval = {
+                          { .ival = "repeat",
+                            .oval = DEDUPE_MODE_REPEAT,
+                            .help = "repeat previous page",
+                          },
+                          { .ival = "working_set",
+                            .oval = DEDUPE_MODE_WORKING_SET,
+                            .help = "choose a page randomly from limited working set defined in dedupe_working_set_percentage",
+                          },
+               },
+       },
+       {
+               .name   = "dedupe_working_set_percentage",
+               .lname  = "Dedupe working set percentage",
+               .help   = "Dedupe working set size in percentages from file or device size used to generate dedupe patterns from",
+               .type   = FIO_OPT_INT,
+               .off1   = offsetof(struct thread_options, dedupe_working_set_percentage),
+               .parent = "dedupe_percentage",
+               .def    = "5",
+               .maxval = 100,
+               .minval = 0,
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IO_BUF,
+       },
        {
                .name   = "clat_percentiles",
                .lname  = "Completion latency percentiles",
@@ -4616,12 +4684,39 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
        {
                .name   = "unified_rw_reporting",
                .lname  = "Unified RW Reporting",
-               .type   = FIO_OPT_BOOL,
+               .type   = FIO_OPT_STR,
                .off1   = offsetof(struct thread_options, unified_rw_rep),
                .help   = "Unify reporting across data direction",
-               .def    = "0",
+               .def    = "none",
                .category = FIO_OPT_C_GENERAL,
                .group  = FIO_OPT_G_INVALID,
+               .posval = {
+                         { .ival = "none",
+                           .oval = UNIFIED_SPLIT,
+                           .help = "Normal statistics reporting",
+                         },
+                         { .ival = "mixed",
+                           .oval = UNIFIED_MIXED,
+                           .help = "Statistics are summed per data direction and reported together",
+                         },
+                         { .ival = "both",
+                           .oval = UNIFIED_BOTH,
+                           .help = "Statistics are reported normally, followed by the mixed statistics"
+                         },
+                         /* Compatibility with former boolean values */
+                         { .ival = "0",
+                           .oval = UNIFIED_SPLIT,
+                           .help = "Alias for 'none'",
+                         },
+                         { .ival = "1",
+                           .oval = UNIFIED_MIXED,
+                           .help = "Alias for 'mixed'",
+                         },
+                         { .ival = "2",
+                           .oval = UNIFIED_BOTH,
+                           .help = "Alias for 'both'",
+                         },
+               },
        },
        {
                .name   = "continue_on_error",
@@ -5454,6 +5549,19 @@ void fio_options_free(struct thread_data *td)
        }
 }
 
+void fio_dump_options_free(struct thread_data *td)
+{
+       while (!flist_empty(&td->opt_list)) {
+               struct print_option *p;
+
+               p = flist_first_entry(&td->opt_list, struct print_option, list);
+               flist_del_init(&p->list);
+               free(p->name);
+               free(p->value);
+               free(p);
+       }
+}
+
 struct fio_option *fio_option_find(const char *name)
 {
        return find_option(fio_options, name);