arm64: ensure CPU clock retrieval issues isb()
[fio.git] / fio.h
diff --git a/fio.h b/fio.h
index 53bcda1315f9b88858e6cf2f41b37b03b4380bd5..de7eca79cb1a42c53dcbd0e6d4ca9d6a89f75eff 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -36,6 +36,8 @@
 #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"
@@ -45,6 +47,7 @@
 #include "workqueue.h"
 #include "steadystate.h"
 #include "lib/nowarn_snprintf.h"
+#include "dedupe.h"
 
 #ifdef CONFIG_SOLARISAIO
 #include <sys/asynch.h>
@@ -94,6 +97,7 @@ enum {
        __TD_F_MMAP_KEEP,
        __TD_F_DIRS_CREATED,
        __TD_F_CHECK_RATE,
+       __TD_F_SYNCS,
        __TD_F_LAST,            /* not a real bit, keep last */
 };
 
@@ -115,6 +119,7 @@ enum {
        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 {
@@ -137,6 +142,8 @@ 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,
 };
 
@@ -146,6 +153,9 @@ enum {
 
        RATE_PROCESS_LINEAR = 0,
        RATE_PROCESS_POISSON = 1,
+
+       THINKTIME_BLOCKS_TYPE_COMPLETE = 0,
+       THINKTIME_BLOCKS_TYPE_ISSUE = 1,
 };
 
 enum {
@@ -169,14 +179,12 @@ struct zone_split_index {
        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;
@@ -228,6 +236,7 @@ struct thread_data {
                double pareto_h;
                double gauss_dev;
        };
+       double random_center;
        int error;
        int sig;
        int done;
@@ -245,7 +254,7 @@ struct thread_data {
        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;
@@ -254,10 +263,17 @@ struct thread_data {
 
        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;
@@ -266,6 +282,11 @@ struct thread_data {
 
        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.
@@ -277,7 +298,6 @@ struct thread_data {
         * IO engine private data and dlhandle.
         */
        void *io_ops_data;
-       void *io_ops_dlhandle;
 
        /*
         * Queue depth of io_u's that fio MIGHT do
@@ -317,10 +337,10 @@ struct thread_data {
         */
        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];
 
@@ -351,6 +371,10 @@ struct thread_data {
        struct fio_sem *sem;
        uint64_t bytes_done[DDIR_RWDIR_CNT];
 
+       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
         */
@@ -358,7 +382,7 @@ struct thread_data {
 
        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;
@@ -375,6 +399,7 @@ struct thread_data {
        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;
 
@@ -404,9 +429,14 @@ struct thread_data {
         */
        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;
 
        /*
@@ -436,6 +466,7 @@ struct thread_data {
        int first_error;
 
        struct fio_flow *flow;
+       unsigned long long flow_counter;
 
        /*
         * Can be overloaded by profiles
@@ -458,10 +489,16 @@ struct thread_data {
        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;
+};
+
 /*
  * when should interactive ETA output be generated
  */
@@ -505,10 +542,15 @@ enum {
 #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;
@@ -537,7 +579,15 @@ extern char *trigger_remote_cmd;
 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)
 {
@@ -552,8 +602,6 @@ static inline void fio_ro_check(const struct thread_data *td, struct io_u *io_u)
               !(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)
@@ -634,13 +682,13 @@ enum {
        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,
@@ -660,8 +708,14 @@ extern const char *runstate_to_name(int runstate);
  */
 #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 *);
 
 /*
@@ -698,23 +752,13 @@ extern void lat_target_reset(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 ||
@@ -738,17 +782,9 @@ static inline bool option_check_rate(struct thread_data *td, enum fio_ddir ddir)
        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)
@@ -772,6 +808,11 @@ static inline bool td_async_processing(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
@@ -852,4 +893,17 @@ enum {
 extern void exec_trigger(const char *);
 extern void check_trigger_file(void);
 
+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