#include <string.h>
#include <errno.h>
#include <sys/ipc.h>
+#ifndef FIO_NO_HAVE_SHM_H
#include <sys/shm.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
#include "verify.h"
#include "profile.h"
#include "server.h"
+#include "idletime.h"
#include "lib/getopt.h"
int exitall_on_terminate = 0;
int output_format = FIO_OUTPUT_NORMAL;
-int eta_print;
+int eta_print = FIO_ETA_AUTO;
unsigned long long mlock_size = 0;
FILE *f_out = NULL;
FILE *f_err = NULL;
static char cmd_optstr[256];
static int did_arg;
-const fio_fp64_t def_percentile_list[FIO_IO_U_LIST_MAX_LEN] = {
- { .u.f = 1.00 },
- { .u.f = 5.00 },
- { .u.f = 10.00 },
- { .u.f = 20.00 },
- { .u.f = 30.00 },
- { .u.f = 40.00 },
- { .u.f = 50.00 },
- { .u.f = 60.00 },
- { .u.f = 70.00 },
- { .u.f = 80.00 },
- { .u.f = 90.00 },
- { .u.f = 95.00 },
- { .u.f = 99.00 },
- { .u.f = 99.50 },
- { .u.f = 99.90 },
- { .u.f = 99.95 },
- { .u.f = 99.99 },
-};
-
#define FIO_CLIENT_FLAG (1 << 16)
/*
.has_arg = required_argument,
.val = 'C',
},
+ {
+ .name = (char *) "cpuclock-test",
+ .has_arg = no_argument,
+ .val = 'T',
+ },
+ {
+ .name = (char *) "idle-prof",
+ .has_arg = required_argument,
+ .val = 'I',
+ },
{
.name = NULL,
},
/*
* only really works with 1 file
*/
- if (o->zone_size && o->open_files == 1)
+ if (o->zone_size && o->open_files > 1)
o->zone_size = 0;
/*
/*
* The low water mark cannot be bigger than the iodepth
*/
- if (o->iodepth_low > o->iodepth || !o->iodepth_low) {
- /*
- * syslet work around - if the workload is sequential,
- * we want to let the queue drain all the way down to
- * avoid seeking between async threads
- */
- if (!strcmp(td->io_ops->name, "syslet-rw") && !td_random(td))
- o->iodepth_low = 1;
- else
- o->iodepth_low = o->iodepth;
- }
+ if (o->iodepth_low > o->iodepth || !o->iodepth_low)
+ o->iodepth_low = o->iodepth;
/*
* If batch number isn't set, default to the same as iodepth
}
}
-#ifndef FIO_HAVE_FDATASYNC
+#ifndef CONFIG_FDATASYNC
if (o->fdatasync_blocks) {
log_info("fio: this platform does not support fdatasync()"
" falling back to using fsync(). Use the 'fsync'"
p++;
} while (*p);
- snprintf(buf, 31, "%u%c", val, *p);
+ snprintf(buf, 32, "%u%c", val, *p);
return buf;
}
static void td_fill_rand_seeds_os(struct thread_data *td)
{
- os_random_seed(td->rand_seeds[0], &td->bsrange_state);
- os_random_seed(td->rand_seeds[1], &td->verify_state);
- os_random_seed(td->rand_seeds[2], &td->rwmix_state);
+ os_random_seed(td->rand_seeds[FIO_RAND_BS_OFF], &td->bsrange_state);
+ os_random_seed(td->rand_seeds[FIO_RAND_VER_OFF], &td->verify_state);
+ os_random_seed(td->rand_seeds[FIO_RAND_MIX_OFF], &td->rwmix_state);
if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
- os_random_seed(td->rand_seeds[3], &td->next_file_state);
+ os_random_seed(td->rand_seeds[FIO_RAND_FILE_OFF], &td->next_file_state);
- os_random_seed(td->rand_seeds[5], &td->file_size_state);
- os_random_seed(td->rand_seeds[6], &td->trim_state);
+ os_random_seed(td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], &td->file_size_state);
+ os_random_seed(td->rand_seeds[FIO_RAND_TRIM_OFF], &td->trim_state);
if (!td_random(td))
return;
if (td->o.rand_repeatable)
- td->rand_seeds[4] = FIO_RANDSEED * td->thread_number;
+ td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
- os_random_seed(td->rand_seeds[4], &td->random_state);
+ os_random_seed(td->rand_seeds[FIO_RAND_BLOCK_OFF], &td->random_state);
}
static void td_fill_rand_seeds_internal(struct thread_data *td)
{
- init_rand_seed(&td->__bsrange_state, td->rand_seeds[0]);
- init_rand_seed(&td->__verify_state, td->rand_seeds[1]);
- init_rand_seed(&td->__rwmix_state, td->rand_seeds[2]);
+ init_rand_seed(&td->__bsrange_state, td->rand_seeds[FIO_RAND_BS_OFF]);
+ init_rand_seed(&td->__verify_state, td->rand_seeds[FIO_RAND_VER_OFF]);
+ init_rand_seed(&td->__rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF]);
if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
- init_rand_seed(&td->__next_file_state, td->rand_seeds[3]);
+ init_rand_seed(&td->__next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF]);
- init_rand_seed(&td->__file_size_state, td->rand_seeds[5]);
- init_rand_seed(&td->__trim_state, td->rand_seeds[6]);
+ init_rand_seed(&td->__file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF]);
+ init_rand_seed(&td->__trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF]);
if (!td_random(td))
return;
if (td->o.rand_repeatable)
- td->rand_seeds[4] = FIO_RANDSEED * td->thread_number;
+ td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
- init_rand_seed(&td->__random_state, td->rand_seeds[4]);
+ init_rand_seed(&td->__random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF]);
}
void td_fill_rand_seeds(struct thread_data *td)
else
td_fill_rand_seeds_internal(td);
- init_rand_seed(&td->buf_state, td->rand_seeds[7]);
+ init_rand_seed(&td->buf_state, td->rand_seeds[FIO_RAND_BUF_OFF]);
}
-
/*
* Initializes the ioengine configured for a job, if it has not been done so
* already.
return 0;
}
+static void init_flags(struct thread_data *td)
+{
+ struct thread_options *o = &td->o;
+
+ if (o->verify_backlog)
+ td->flags |= TD_F_VER_BACKLOG;
+ if (o->trim_backlog)
+ td->flags |= TD_F_TRIM_BACKLOG;
+ if (o->read_iolog_file)
+ td->flags |= TD_F_READ_IOLOG;
+ if (o->refill_buffers)
+ td->flags |= TD_F_REFILL_BUFFERS;
+ if (o->scramble_buffers)
+ td->flags |= TD_F_SCRAMBLE_BUFFERS;
+ if (o->verify != VERIFY_NONE)
+ td->flags |= TD_F_VER_NONE;
+}
+
+static int setup_random_seeds(struct thread_data *td)
+{
+ unsigned long seed;
+ unsigned int i;
+
+ if (!td->o.rand_repeatable)
+ return init_random_state(td, td->rand_seeds, sizeof(td->rand_seeds));
+
+ for (seed = 0x89, i = 0; i < 4; i++)
+ seed *= 0x9e370001UL;
+
+ for (i = 0; i < FIO_RAND_NR_OFFS; i++) {
+ td->rand_seeds[i] = seed;
+ seed *= 0x9e370001UL;
+ }
+
+ td_fill_rand_seeds(td);
+ return 0;
+}
+
/*
* Adds a job to the list of things todo. Sanitizes the various options
* to make sure we don't have conflicts, and initializes various
if (td == &def_thread)
return 0;
+ init_flags(td);
+
/*
* if we are just dumping the output command line, don't add the job
*/
td->mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
td->ts.clat_percentiles = td->o.clat_percentiles;
- if (td->o.overwrite_plist)
- memcpy(td->ts.percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
- else
- memcpy(td->ts.percentile_list, def_percentile_list, sizeof(def_percentile_list));
+ td->ts.percentile_precision = td->o.percentile_precision;
+ memcpy(td->ts.percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
for (i = 0; i < DDIR_RWDIR_CNT; i++) {
td->ts.clat_stat[i].min_val = ULONG_MAX;
td->groupid = groupid;
prev_group_jobs++;
- if (init_random_state(td, td->rand_seeds, sizeof(td->rand_seeds))) {
+ if (setup_random_seeds(td)) {
td_verror(td, errno, "init_random_state");
goto err;
}
printf(" --terse-version=x\tSet terse version output format to 'x'\n");
printf(" --version\t\tPrint version info and exit\n");
printf(" --help\t\tPrint this page\n");
+ printf(" --cpuclock-test\tPerform test/validation of CPU clock\n");
printf(" --cmdhelp=cmd\t\tPrint command help, \"all\" for all of"
" them\n");
printf(" --enghelp=engine\tPrint ioengine help, or list"
printf(" --server=args\t\tStart a backend fio server\n");
printf(" --daemonize=pidfile\tBackground fio server, write pid to file\n");
printf(" --client=hostname\tTalk to remote backend fio server at hostname\n");
+ printf(" --idle-prof=option\tReport cpu idleness on a system or percpu basis\n"
+ "\t\t\t(option=system,percpu) or run unit work\n"
+ "\t\t\tcalibration only (option=calibrate)\n");
printf("\nFio was written by Jens Axboe <jens.axboe@oracle.com>");
- printf("\n Jens Axboe <jaxboe@fusionio.com>\n");
+ printf("\n Jens Axboe <jaxboe@fusionio.com>\n");
}
#ifdef FIO_INC_DEBUG
case 'D':
pid_file = strdup(optarg);
break;
+ case 'I':
+ if ((ret = fio_idle_prof_parse_opt(optarg))) {
+ /* exit on error and calibration only */
+ do_exit++;
+ if (ret == -1)
+ exit_val = 1;
+ }
+ break;
case 'C':
if (is_backend) {
log_err("fio: can't be both client and server\n");
optind++;
}
break;
+ case 'T':
+ do_exit++;
+ exit_val = fio_monotonic_clocktest();
+ break;
+ case '?':
+ log_err("%s: unrecognized option '%s'\n", argv[0],
+ argv[optind - 1]);
default:
do_exit++;
exit_val = 1;