struct thread_options *o = &td->o;
pthread_condattr_t attr;
int clear_state;
+ int ret;
if (!o->use_thread) {
setsid();
} else
td->pid = gettid();
- fio_local_clock_init(td->o.use_thread);
+ fio_local_clock_init(o->use_thread);
dprint(FD_PROCESS, "jobs pid=%d started\n", (int) td->pid);
+ if (is_backend)
+ fio_server_send_start(td);
+
INIT_FLIST_HEAD(&td->io_u_freelist);
INIT_FLIST_HEAD(&td->io_u_busylist);
INIT_FLIST_HEAD(&td->io_u_requeues);
* eating a file descriptor
*/
fio_mutex_remove(td->mutex);
+ td->mutex = NULL;
/*
* A new gid requires privilege, so we need to do this before setting
* allocations.
*/
if (o->cpumask_set) {
- if (fio_setaffinity(td->pid, o->cpumask) == -1) {
+ ret = fio_setaffinity(td->pid, o->cpumask);
+ if (ret == -1) {
td_verror(td, errno, "cpu_set_affinity");
goto err;
}
#ifdef CONFIG_LIBNUMA
/* numa node setup */
- if (td->o.numa_cpumask_set || td->o.numa_memmask_set) {
+ if (o->numa_cpumask_set || o->numa_memmask_set) {
int ret;
if (numa_available() < 0) {
goto err;
}
- if (td->o.numa_cpumask_set) {
- ret = numa_run_on_node_mask(td->o.numa_cpunodesmask);
+ if (o->numa_cpumask_set) {
+ ret = numa_run_on_node_mask(o->numa_cpunodesmask);
if (ret == -1) {
td_verror(td, errno, \
"numa_run_on_node_mask failed\n");
}
}
- if (td->o.numa_memmask_set) {
+ if (o->numa_memmask_set) {
- switch (td->o.numa_mem_mode) {
+ switch (o->numa_mem_mode) {
case MPOL_INTERLEAVE:
- numa_set_interleave_mask(td->o.numa_memnodesmask);
+ numa_set_interleave_mask(o->numa_memnodesmask);
break;
case MPOL_BIND:
- numa_set_membind(td->o.numa_memnodesmask);
+ numa_set_membind(o->numa_memnodesmask);
break;
case MPOL_LOCAL:
numa_set_localalloc();
break;
case MPOL_PREFERRED:
- numa_set_preferred(td->o.numa_mem_prefer_node);
+ numa_set_preferred(o->numa_mem_prefer_node);
break;
case MPOL_DEFAULT:
default:
}
#endif
+ if (fio_pin_memory(td))
+ goto err;
+
/*
* May alter parameters that init_io_u() will use, so we need to
* do this first.
if (o->verify_async && verify_async_init(td))
goto err;
- if (td->ioprio_set) {
- if (ioprio_set(IOPRIO_WHO_PROCESS, 0, td->ioprio) == -1) {
+ if (o->ioprio) {
+ ret = ioprio_set(IOPRIO_WHO_PROCESS, 0, o->ioprio_class, o->ioprio);
+ if (ret == -1) {
td_verror(td, errno, "ioprio_set");
goto err;
}
}
- if (td->o.cgroup && cgroup_setup(td, cgroup_list, &cgroup_mnt))
+ if (o->cgroup && cgroup_setup(td, cgroup_list, &cgroup_mnt))
goto err;
errno = 0;
memcpy(&td->iops_sample_time, &td->start, sizeof(td->start));
memcpy(&td->tv_cache, &td->start, sizeof(td->start));
- if (td->o.ratemin[DDIR_READ] || td->o.ratemin[DDIR_WRITE] ||
- td->o.ratemin[DDIR_TRIM]) {
+ if (o->ratemin[DDIR_READ] || o->ratemin[DDIR_WRITE] ||
+ o->ratemin[DDIR_TRIM]) {
memcpy(&td->lastrate[DDIR_READ], &td->bw_sample_time,
sizeof(td->bw_sample_time));
memcpy(&td->lastrate[DDIR_WRITE], &td->bw_sample_time,
if (td->error || td->terminate)
break;
- if (!td->o.do_verify ||
- td->o.verify == VERIFY_NONE ||
+ if (!o->do_verify ||
+ o->verify == VERIFY_NONE ||
(td->io_ops->flags & FIO_UNIDIR))
continue;
fio_mutex_down(writeout_mutex);
if (td->bw_log) {
- if (td->o.bw_log_file) {
+ if (o->bw_log_file) {
finish_log_named(td, td->bw_log,
- td->o.bw_log_file, "bw");
+ o->bw_log_file, "bw");
} else
finish_log(td, td->bw_log, "bw");
}
if (td->lat_log) {
- if (td->o.lat_log_file) {
+ if (o->lat_log_file) {
finish_log_named(td, td->lat_log,
- td->o.lat_log_file, "lat");
+ o->lat_log_file, "lat");
} else
finish_log(td, td->lat_log, "lat");
}
if (td->slat_log) {
- if (td->o.lat_log_file) {
+ if (o->lat_log_file) {
finish_log_named(td, td->slat_log,
- td->o.lat_log_file, "slat");
+ o->lat_log_file, "slat");
} else
finish_log(td, td->slat_log, "slat");
}
if (td->clat_log) {
- if (td->o.lat_log_file) {
+ if (o->lat_log_file) {
finish_log_named(td, td->clat_log,
- td->o.lat_log_file, "clat");
+ o->lat_log_file, "clat");
} else
finish_log(td, td->clat_log, "clat");
}
if (td->iops_log) {
- if (td->o.iops_log_file) {
+ if (o->iops_log_file) {
finish_log_named(td, td->iops_log,
- td->o.iops_log_file, "iops");
+ o->iops_log_file, "iops");
} else
finish_log(td, td->iops_log, "iops");
}
fio_mutex_up(writeout_mutex);
- if (td->o.exec_postrun)
- exec_string(td->o.exec_postrun);
+ if (o->exec_postrun)
+ exec_string(o->exec_postrun);
if (exitall_on_terminate)
fio_terminate_threads(td->groupid);
log_info("fio: pid=%d, err=%d/%s\n", (int) td->pid, td->error,
td->verror);
- if (td->o.verify_async)
+ if (o->verify_async)
verify_async_exit(td);
close_and_free_files(td);
/*
* do this very late, it will log file closing as well
*/
- if (td->o.write_iolog_file)
+ if (o->write_iolog_file)
write_iolog_close(td);
fio_mutex_remove(td->rusage_sem);
reap_threads(&nr_running, &t_rate, &m_rate);
- if (todo) {
- if (is_backend)
- fio_server_idle_loop();
- else
- usleep(100000);
- }
+ if (todo)
+ usleep(100000);
}
while (nr_running) {
reap_threads(&nr_running, &t_rate, &m_rate);
-
- if (is_backend)
- fio_server_idle_loop();
- else
- usleep(10000);
+ usleep(10000);
}
fio_idle_prof_stop();
#include "thread_options.h"
#include "flist.h"
#include "fifo.h"
-#include "lib/rbtree.h"
#include "arch/arch.h"
#include "os/os.h"
#include "mutex.h"
#include "gettime.h"
#include "lib/getopt.h"
#include "lib/rand.h"
+#include "lib/rbtree.h"
+ #include "client.h"
#include "server.h"
#include "stat.h"
#include "flow.h"
void *eo;
char verror[FIO_VERROR_SIZE];
pthread_t thread;
- int thread_number;
- int groupid;
+ unsigned int thread_number;
+ unsigned int groupid;
struct thread_stat ts;
+ int client_type;
+
struct io_log *slat_log;
struct io_log *clat_log;
struct io_log *lat_log;
size_t orig_buffer_size;
volatile int terminate;
volatile int runstate;
- unsigned int ioprio;
- unsigned int ioprio_set;
unsigned int last_was_sync;
enum fio_ddir last_ddir;
- char *mmapfile;
int mmapfd;
void *iolog_buf;
/*
* Init/option functions
*/
+ extern int __must_check fio_init_options(void);
extern int __must_check parse_options(int, char **);
- extern int parse_jobs_ini(char *, int, int);
- extern int parse_cmd_line(int, char **);
+ extern int parse_jobs_ini(char *, int, int, int);
+ extern int parse_cmd_line(int, char **, int);
extern int fio_backend(void);
extern void reset_fio_state(void);
extern void clear_io_state(struct thread_data *);
extern void fio_options_mem_dupe(struct thread_data *);
extern void options_mem_dupe(void *data, struct fio_option *options);
extern void td_fill_rand_seeds(struct thread_data *);
- extern void add_job_opts(const char **);
+ extern void add_job_opts(const char **, int);
extern char *num2str(unsigned long, int, int, int, int);
extern int ioengine_load(struct thread_data *);
-extern unsigned long page_mask;
-extern unsigned long page_size;
+extern uintptr_t page_mask;
+extern uintptr_t page_size;
extern int initialize_fio(char *envp[]);
#define FIO_GETOPT_JOB 0x89000000
extern void fio_unpin_memory(struct thread_data *);
extern int __must_check allocate_io_mem(struct thread_data *);
extern void free_io_mem(struct thread_data *);
+ extern void free_threads_shm(void);
/*
* Reset stats after ramp time completes
extern const char *fio_get_arch_string(int);
extern const char *fio_get_os_string(int);
+ #define ARRAY_SIZE(x) (sizeof((x)) / (sizeof((x)[0])))
+
enum {
FIO_OUTPUT_TERSE = 0,
FIO_OUTPUT_JSON,
#include "os/os.h"
#include "stat.h"
#include "gettime.h"
+#include "lib/ieee754.h"
/*
* What type of allocation to use for io buffers
char *filename_format;
char *opendir;
char *ioengine;
+ char *mmapfile;
enum td_ddir td_ddir;
unsigned int rw_seq;
unsigned int kb_base;
unsigned int override_sync;
unsigned int rand_repeatable;
unsigned int use_os_rand;
- unsigned int write_lat_log;
- unsigned int write_bw_log;
- unsigned int write_iops_log;
unsigned int log_avg_msec;
unsigned int norandommap;
unsigned int softrandommap;
unsigned int fsync_on_close;
unsigned int random_distribution;
+
fio_fp64_t zipf_theta;
fio_fp64_t pareto_h;
char *ioscheduler;
- /*
- * CPU "io" cycle burner
- */
- unsigned int cpuload;
- unsigned int cpucycle;
-
/*
* I/O Error handling
*/
unsigned int sync_file_range;
};
+ #define FIO_TOP_STR_MAX 256
+
+ struct thread_options_pack {
+ uint8_t description[FIO_TOP_STR_MAX];
+ uint8_t name[FIO_TOP_STR_MAX];
+ uint8_t directory[FIO_TOP_STR_MAX];
+ uint8_t filename[FIO_TOP_STR_MAX];
+ uint8_t filename_format[FIO_TOP_STR_MAX];
+ uint8_t opendir[FIO_TOP_STR_MAX];
+ uint8_t ioengine[FIO_TOP_STR_MAX];
+ uint8_t mmapfile[FIO_TOP_STR_MAX];
+ uint32_t td_ddir;
+ uint32_t rw_seq;
+ uint32_t kb_base;
+ uint32_t unit_base;
+ uint32_t ddir_seq_nr;
+ uint64_t ddir_seq_add;
+ uint32_t iodepth;
+ uint32_t iodepth_low;
+ uint32_t iodepth_batch;
+ uint32_t iodepth_batch_complete;
+
+ uint64_t size;
+ uint32_t size_percent;
+ uint32_t fill_device;
+ uint64_t file_size_low;
+ uint64_t file_size_high;
+ uint64_t start_offset;
+
+ uint32_t bs[DDIR_RWDIR_CNT];
+ uint32_t ba[DDIR_RWDIR_CNT];
+ uint32_t min_bs[DDIR_RWDIR_CNT];
+ uint32_t max_bs[DDIR_RWDIR_CNT];
+ struct bssplit bssplit[DDIR_RWDIR_CNT][BSSPLIT_MAX];
+ uint32_t bssplit_nr[DDIR_RWDIR_CNT];
+
+ uint32_t ignore_error[ERROR_TYPE_CNT][ERROR_STR_MAX];
+ uint32_t ignore_error_nr[ERROR_TYPE_CNT];
+ uint32_t error_dump;
+
+ uint32_t nr_files;
+ uint32_t open_files;
+ uint32_t file_lock_mode;
+
+ uint32_t odirect;
+ uint32_t invalidate_cache;
+ uint32_t create_serialize;
+ uint32_t create_fsync;
+ uint32_t create_on_open;
+ uint32_t create_only;
+ uint32_t end_fsync;
+ uint32_t pre_read;
+ uint32_t sync_io;
+ uint32_t verify;
+ uint32_t do_verify;
+ uint32_t verifysort;
+ uint32_t verifysort_nr;
+ uint32_t verify_interval;
+ uint32_t verify_offset;
+ uint8_t verify_pattern[MAX_PATTERN_SIZE];
+ uint32_t verify_pattern_bytes;
+ uint32_t verify_fatal;
+ uint32_t verify_dump;
+ uint32_t verify_async;
+ uint64_t verify_backlog;
+ uint32_t verify_batch;
+ uint32_t experimental_verify;
+ uint32_t use_thread;
+ uint32_t unlink;
+ uint32_t do_disk_util;
+ uint32_t override_sync;
+ uint32_t rand_repeatable;
+ uint32_t use_os_rand;
+ uint32_t log_avg_msec;
+ uint32_t norandommap;
+ uint32_t softrandommap;
+ uint32_t bs_unaligned;
+ uint32_t fsync_on_close;
+
+ uint32_t random_distribution;
+ fio_fp64_t zipf_theta;
+ fio_fp64_t pareto_h;
+
+ uint32_t random_generator;
+
+ uint32_t hugepage_size;
+ uint32_t rw_min_bs;
+ uint32_t thinktime;
+ uint32_t thinktime_spin;
+ uint32_t thinktime_blocks;
+ uint32_t fsync_blocks;
+ uint32_t fdatasync_blocks;
+ uint32_t barrier_blocks;
+ uint64_t start_delay;
+ uint64_t timeout;
+ uint64_t ramp_time;
+ uint32_t overwrite;
+ uint32_t bw_avg_time;
+ uint32_t iops_avg_time;
+ uint32_t loops;
+ uint64_t zone_range;
+ uint64_t zone_size;
+ uint64_t zone_skip;
+ uint64_t lockmem;
+ uint32_t mem_type;
+ uint32_t mem_align;
+
+ uint32_t max_latency;
+
+ uint32_t stonewall;
+ uint32_t new_group;
+ uint32_t numjobs;
+ uint8_t cpumask[FIO_TOP_STR_MAX];
+ uint32_t cpumask_set;
+ uint8_t verify_cpumask[FIO_TOP_STR_MAX];
+ uint32_t verify_cpumask_set;
+ uint32_t iolog;
+ uint32_t rwmixcycle;
+ uint32_t rwmix[2];
+ uint32_t nice;
+ uint32_t ioprio;
+ uint32_t ioprio_class;
+ uint32_t file_service_type;
+ uint32_t group_reporting;
+ uint32_t fadvise_hint;
+ uint32_t fallocate_mode;
+ uint32_t zero_buffers;
+ uint32_t refill_buffers;
+ uint32_t scramble_buffers;
+ unsigned int compress_percentage;
+ unsigned int compress_chunk;
+ uint32_t time_based;
+ uint32_t disable_lat;
+ uint32_t disable_clat;
+ uint32_t disable_slat;
+ uint32_t disable_bw;
+ uint32_t unified_rw_rep;
+ uint32_t gtod_reduce;
+ uint32_t gtod_cpu;
+ uint32_t gtod_offload;
+ uint32_t clocksource;
+ uint32_t no_stall;
+ uint32_t trim_percentage;
+ uint32_t trim_batch;
+ uint32_t trim_zero;
+ uint64_t trim_backlog;
+ uint32_t clat_percentiles;
+ uint32_t percentile_precision;
+ fio_fp64_t percentile_list[FIO_IO_U_LIST_MAX_LEN];
+
+ uint8_t read_iolog_file[FIO_TOP_STR_MAX];
+ uint8_t write_iolog_file[FIO_TOP_STR_MAX];
+ uint8_t bw_log_file[FIO_TOP_STR_MAX];
+ uint8_t lat_log_file[FIO_TOP_STR_MAX];
+ uint8_t iops_log_file[FIO_TOP_STR_MAX];
+ uint8_t replay_redirect[FIO_TOP_STR_MAX];
+
+ /*
+ * Pre-run and post-run shell
+ */
+ uint8_t exec_prerun[FIO_TOP_STR_MAX];
+ uint8_t exec_postrun[FIO_TOP_STR_MAX];
+
+ uint32_t rate[DDIR_RWDIR_CNT];
+ uint32_t ratemin[DDIR_RWDIR_CNT];
+ uint32_t ratecycle;
+ uint32_t rate_iops[DDIR_RWDIR_CNT];
+ uint32_t rate_iops_min[DDIR_RWDIR_CNT];
+
+ uint8_t ioscheduler[FIO_TOP_STR_MAX];
+
+ /*
+ * I/O Error handling
+ */
+ uint32_t continue_on_error;
+
+ /*
+ * Benchmark profile type
+ */
+ uint8_t profile[FIO_TOP_STR_MAX];
+
+ /*
+ * blkio cgroup support
+ */
+ uint8_t cgroup[FIO_TOP_STR_MAX];
+ uint32_t cgroup_weight;
+ uint32_t cgroup_nodelete;
+
+ uint32_t uid;
+ uint32_t gid;
+
+ int32_t flow_id;
+ int32_t flow;
+ int32_t flow_watermark;
+ uint32_t flow_sleep;
+
+ uint64_t offset_increment;
+
+ uint32_t sync_file_range;
+ } __attribute__((packed));
+
+ extern void convert_thread_options_to_cpu(struct thread_options *o, struct thread_options_pack *top);
+ extern void convert_thread_options_to_net(struct thread_options_pack *top, struct thread_options *);
+ extern int fio_test_cconv(struct thread_options *);
+ extern void options_default_fill(struct thread_options *o);
+
#endif