#include "lib/rand.h"
#include "lib/rbtree.h"
#include "lib/num2str.h"
+#include "lib/memalign.h"
+#include "smalloc.h"
#include "client.h"
#include "server.h"
#include "stat.h"
#include "workqueue.h"
#include "steadystate.h"
#include "lib/nowarn_snprintf.h"
+#include "dedupe.h"
#ifdef CONFIG_SOLARISAIO
#include <sys/asynch.h>
__TD_F_MMAP_KEEP,
__TD_F_DIRS_CREATED,
__TD_F_CHECK_RATE,
+ __TD_F_SYNCS,
__TD_F_LAST, /* not a real bit, keep last */
};
TD_F_MMAP_KEEP = 1U << __TD_F_MMAP_KEEP,
TD_F_DIRS_CREATED = 1U << __TD_F_DIRS_CREATED,
TD_F_CHECK_RATE = 1U << __TD_F_CHECK_RATE,
+ TD_F_SYNCS = 1U << __TD_F_SYNCS,
};
enum {
FIO_RAND_ZONE_OFF,
FIO_RAND_POISSON2_OFF,
FIO_RAND_POISSON3_OFF,
+ FIO_RAND_PRIO_CMDS,
+ FIO_RAND_DEDUPE_WORKING_SET_IX,
FIO_RAND_NR_OFFS,
};
RATE_PROCESS_LINEAR = 0,
RATE_PROCESS_POISSON = 1,
+
+ THINKTIME_BLOCKS_TYPE_COMPLETE = 0,
+ THINKTIME_BLOCKS_TYPE_ISSUE = 1,
};
enum {
uint64_t size_prev;
};
-#define FIO_MAX_OPEN_ZBD_ZONES 128
-
/*
* This describes a single thread/process executing a fio job.
*/
struct thread_data {
struct flist_head opt_list;
- unsigned long flags;
+ unsigned long long flags;
struct thread_options o;
void *eo;
pthread_t thread;
double pareto_h;
double gauss_dev;
};
+ double random_center;
int error;
int sig;
int done;
void *iolog_buf;
FILE *iolog_f;
- unsigned long rand_seeds[FIO_RAND_NR_OFFS];
+ uint64_t rand_seeds[FIO_RAND_NR_OFFS];
struct frand_state bsrange_state[DDIR_RWDIR_CNT];
struct frand_state verify_state;
+ struct frand_state verify_state_last_do_io;
struct frand_state trim_state;
struct frand_state delay_state;
struct frand_state buf_state;
struct frand_state buf_state_prev;
+ struct frand_state buf_state_ret;
struct frand_state dedupe_state;
struct frand_state zone_state;
+ struct frand_state prio_state;
+ struct frand_state dedupe_working_set_index_state;
+ struct frand_state *dedupe_working_set_states;
+
+ unsigned long long num_unique_pages;
struct zone_split_index **zone_state_index;
+ unsigned int num_open_zones;
unsigned int verify_batch;
unsigned int trim_batch;
int shm_id;
+ /*
+ * Job default IO priority set with prioclass and prio options.
+ */
+ unsigned int ioprio;
+
/*
* IO engine hooks, contains everything needed to submit an io_u
* to any of the available IO engines.
* IO engine private data and dlhandle.
*/
void *io_ops_data;
- void *io_ops_dlhandle;
/*
* Queue depth of io_u's that fio MIGHT do
*/
uint64_t rate_bps[DDIR_RWDIR_CNT];
uint64_t rate_next_io_time[DDIR_RWDIR_CNT];
- unsigned long rate_bytes[DDIR_RWDIR_CNT];
- unsigned long rate_blocks[DDIR_RWDIR_CNT];
+ unsigned long long last_rate_check_bytes[DDIR_RWDIR_CNT];
+ unsigned long last_rate_check_blocks[DDIR_RWDIR_CNT];
unsigned long long rate_io_issue_bytes[DDIR_RWDIR_CNT];
- struct timespec lastrate[DDIR_RWDIR_CNT];
+ struct timespec last_rate_check_time[DDIR_RWDIR_CNT];
int64_t last_usec[DDIR_RWDIR_CNT];
struct frand_state poisson_state[DDIR_RWDIR_CNT];
* Issue side
*/
uint64_t io_issues[DDIR_RWDIR_CNT];
+ uint64_t verify_read_issues;
uint64_t io_issue_bytes[DDIR_RWDIR_CNT];
uint64_t loops;
uint64_t zone_bytes;
struct fio_sem *sem;
uint64_t bytes_done[DDIR_RWDIR_CNT];
+ uint64_t bytes_verified;
+
+ uint64_t *thinktime_blocks_counter;
+ struct timespec last_thinktime;
+ uint64_t last_thinktime_blocks;
/*
* State for random io, a bitmap of blocks done vs not done
struct timespec start; /* start of this loop */
struct timespec epoch; /* time job was started */
- unsigned long long unix_epoch; /* Time job was started, unix epoch based. */
+ unsigned long long alternate_epoch; /* Time job was started, clock_gettime's clock_id epoch based. */
struct timespec last_issue;
long time_offset;
struct timespec ts_cache;
unsigned int latency_qd_high;
unsigned int latency_qd_low;
unsigned int latency_failed;
+ unsigned int latency_stable_count;
uint64_t latency_ios;
int latency_end_run;
*/
struct flist_head io_log_list;
FILE *io_log_rfile;
+ unsigned int io_log_blktrace;
+ unsigned int io_log_blktrace_swap;
+ unsigned long long io_log_last_ttime;
+ struct timespec io_log_start_time;
unsigned int io_log_current;
unsigned int io_log_checkmark;
unsigned int io_log_highmark;
+ unsigned int io_log_version;
struct timespec io_log_highmark_time;
/*
int first_error;
struct fio_flow *flow;
+ unsigned long long flow_counter;
/*
* Can be overloaded by profiles
CUdevice cu_dev;
CUcontext cu_ctx;
CUdeviceptr dev_mem_ptr;
-#endif
+#endif
+
+};
+struct thread_segment {
+ struct thread_data *threads;
+ int shm_id;
+ int nr_threads;
};
/*
#define __fio_stringify_1(x) #x
#define __fio_stringify(x) __fio_stringify_1(x)
+#define REAL_MAX_JOBS 4096
+#define JOBS_PER_SEG 8
+#define REAL_MAX_SEG (REAL_MAX_JOBS / JOBS_PER_SEG)
+
extern bool exitall_on_terminate;
extern unsigned int thread_number;
extern unsigned int stat_number;
-extern int shm_id;
+extern unsigned int nr_segments;
+extern unsigned int cur_segment;
extern int groupid;
extern int output_format;
extern int append_terse_output;
extern long long trigger_timeout;
extern char *aux_path;
-extern struct thread_data *threads;
+extern struct thread_segment segments[REAL_MAX_SEG];
+
+static inline struct thread_data *tnumber_to_td(unsigned int tnumber)
+{
+ struct thread_segment *seg;
+
+ seg = &segments[tnumber / JOBS_PER_SEG];
+ return &seg->threads[tnumber & (JOBS_PER_SEG - 1)];
+}
static inline bool is_running_backend(void)
{
!(io_u->ddir == DDIR_TRIM && !td_trim(td)));
}
-#define REAL_MAX_JOBS 4096
-
static inline bool should_fsync(struct thread_data *td)
{
if (td->last_was_sync)
TD_NR,
};
-#define TD_ENG_FLAG_SHIFT 17
-#define TD_ENG_FLAG_MASK ((1U << 17) - 1)
+#define TD_ENG_FLAG_SHIFT 18
+#define TD_ENG_FLAG_MASK ((1ULL << 18) - 1)
static inline void td_set_ioengine_flags(struct thread_data *td)
{
td->flags = (~(TD_ENG_FLAG_MASK << TD_ENG_FLAG_SHIFT) & td->flags) |
- (td->io_ops->flags << TD_ENG_FLAG_SHIFT);
+ ((unsigned long long)td->io_ops->flags << TD_ENG_FLAG_SHIFT);
}
static inline bool td_ioengine_flagged(struct thread_data *td,
*/
#define FIO_REAP_TIMEOUT 300
-#define TERMINATE_ALL (-1U)
-extern void fio_terminate_threads(unsigned int);
+enum {
+ TERMINATE_NONE = 0,
+ TERMINATE_GROUP = 1,
+ TERMINATE_STONEWALL = 2,
+ TERMINATE_ALL = -1,
+};
+
+extern void fio_terminate_threads(unsigned int, unsigned int);
extern void fio_mark_td_terminate(struct thread_data *);
/*
* Iterates all threads/processes within all the defined jobs
*/
#define for_each_td(td, i) \
- for ((i) = 0, (td) = &threads[0]; (i) < (int) thread_number; (i)++, (td)++)
+ for ((i) = 0, (td) = &segments[0].threads[0]; (i) < (int) thread_number; (i)++, (td) = tnumber_to_td((i)))
#define for_each_file(td, f, i) \
if ((td)->files_index) \
for ((i) = 0, (f) = (td)->files[0]; \
(i) < (td)->o.nr_files && ((f) = (td)->files[i]) != NULL; \
(i)++)
-#define fio_assert(td, cond) do { \
- if (!(cond)) { \
- int *__foo = NULL; \
- fprintf(stderr, "file:%s:%d, assert %s failed\n", __FILE__, __LINE__, #cond); \
- td_set_runstate((td), TD_EXITED); \
- (td)->error = EFAULT; \
- *__foo = 0; \
- } \
-} while (0)
-
static inline bool fio_fill_issue_time(struct thread_data *td)
{
if (td->o.read_iolog_file ||
return false;
}
-static inline bool __should_check_rate(struct thread_data *td)
-{
- return (td->flags & TD_F_CHECK_RATE) != 0;
-}
-
static inline bool should_check_rate(struct thread_data *td)
{
- if (!__should_check_rate(td))
- return false;
-
- return ddir_rw_sum(td->bytes_done) != 0;
+ return (td->flags & TD_F_CHECK_RATE) != 0;
}
static inline unsigned long long td_max_bs(struct thread_data *td)
return (td->flags & TD_F_NEED_LOCK) != 0;
}
+static inline bool td_offload_overlap(struct thread_data *td)
+{
+ return td->o.serialize_overlap && td->o.io_submit_mode == IO_MODE_OFFLOAD;
+}
+
/*
* We currently only need to do locking if we have verifier threads
* accessing our internal structures too
extern bool in_flight_overlap(struct io_u_queue *q, struct io_u *io_u);
extern pthread_mutex_t overlap_check;
+static inline void *fio_memalign(size_t alignment, size_t size, bool shared)
+{
+ return __fio_memalign(alignment, size, shared ? smalloc : malloc);
+}
+
+static inline void fio_memfree(void *ptr, size_t size, bool shared)
+{
+ return __fio_memfree(ptr, size, shared ? sfree : free);
+}
+
#endif