Suppress uninteresting data race reports
[fio.git] / init.c
diff --git a/init.c b/init.c
index b77b299ef8e310ad91c5e42aecc0a71975dfdd9b..e47e5384119b369891119b54467ed558dfa082c3 100644 (file)
--- a/init.c
+++ b/init.c
 #include <sys/ipc.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <dlfcn.h>
+#ifdef CONFIG_VALGRIND_DEV
+#include <valgrind/drd.h>
+#else
+#define DRD_IGNORE_VAR(x) do { } while (0)
+#endif
 
 #include "fio.h"
 #ifndef FIO_NO_HAVE_SHM_H
@@ -51,6 +57,7 @@ static int nr_job_sections;
 int exitall_on_terminate = 0;
 int output_format = FIO_OUTPUT_NORMAL;
 int eta_print = FIO_ETA_AUTO;
+unsigned int eta_interval_msec = 1000;
 int eta_new_line = 0;
 FILE *f_out = NULL;
 FILE *f_err = NULL;
@@ -77,6 +84,7 @@ static int prev_group_jobs;
 unsigned long fio_debug = 0;
 unsigned int fio_debug_jobno = -1;
 unsigned int *fio_debug_jobp = NULL;
+unsigned int *fio_warned = NULL;
 
 static char cmd_optstr[256];
 static bool did_arg;
@@ -153,6 +161,11 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .has_arg        = required_argument,
                .val            = 'e' | FIO_CLIENT_FLAG,
        },
+       {
+               .name           = (char *) "eta-interval",
+               .has_arg        = required_argument,
+               .val            = 'O' | FIO_CLIENT_FLAG,
+       },
        {
                .name           = (char *) "eta-newline",
                .has_arg        = required_argument,
@@ -302,6 +315,7 @@ static void free_shm(void)
        if (threads) {
                flow_exit();
                fio_debug_jobp = NULL;
+               fio_warned = NULL;
                free_threads_shm();
        }
 
@@ -324,6 +338,8 @@ static void free_shm(void)
  */
 static int setup_thread_area(void)
 {
+       int i;
+
        if (threads)
                return 0;
 
@@ -334,7 +350,7 @@ static int setup_thread_area(void)
        do {
                size_t size = max_jobs * sizeof(struct thread_data);
 
-               size += sizeof(unsigned int);
+               size += 2 * sizeof(unsigned int);
 
 #ifndef CONFIG_NO_SHM
                shm_id = shmget(0, size, IPC_CREAT | 0600);
@@ -367,8 +383,12 @@ static int setup_thread_area(void)
 #endif
 
        memset(threads, 0, max_jobs * sizeof(struct thread_data));
+       for (i = 0; i < max_jobs; i++)
+               DRD_IGNORE_VAR(threads[i]);
        fio_debug_jobp = (unsigned int *)(threads + max_jobs);
        *fio_debug_jobp = -1;
+       fio_warned = fio_debug_jobp + 1;
+       *fio_warned = 0;
 
        flow_init();
 
@@ -795,11 +815,12 @@ static int fixup_options(struct thread_data *td)
                        o->verify_interval = o->min_bs[DDIR_READ];
 
                /*
-                * Verify interval must be a factor or both min and max
+                * Verify interval must be a factor of both min and max
                 * write size
                 */
-               if (o->verify_interval % o->min_bs[DDIR_WRITE] ||
-                   o->verify_interval % o->max_bs[DDIR_WRITE])
+               if (!o->verify_interval ||
+                   (o->min_bs[DDIR_WRITE] % o->verify_interval) ||
+                   (o->max_bs[DDIR_WRITE] % o->verify_interval))
                        o->verify_interval = gcd(o->min_bs[DDIR_WRITE],
                                                        o->max_bs[DDIR_WRITE]);
        }
@@ -931,6 +952,11 @@ static int fixup_options(struct thread_data *td)
                ret = 1;
        }
 
+       if (o->disable_lat)
+               o->lat_percentiles = 0;
+       if (o->disable_clat)
+               o->clat_percentiles = 0;
+
        /*
         * Fix these up to be nsec internally
         */
@@ -1058,6 +1084,9 @@ int ioengine_load(struct thread_data *td)
        }
 
        if (td->io_ops) {
+               struct ioengine_ops *ops;
+               void *dlhandle;
+
                /* An engine is loaded, but the requested ioengine
                 * may have changed.
                 */
@@ -1066,6 +1095,22 @@ int ioengine_load(struct thread_data *td)
                        return 0;
                }
 
+               /*
+                * Name of file and engine may be different, load ops
+                * for this name and see if they match. If they do, then
+                * the engine is unchanged.
+                */
+               dlhandle = td->io_ops_dlhandle;
+               ops = load_ioengine(td);
+               if (ops == td->io_ops && dlhandle == td->io_ops_dlhandle) {
+                       if (dlhandle)
+                               dlclose(dlhandle);
+                       return 0;
+               }
+
+               if (dlhandle && dlhandle != td->io_ops_dlhandle)
+                       dlclose(dlhandle);
+
                /* Unload the old engine. */
                free_ioengine(td);
        }
@@ -1435,12 +1480,13 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                        f->real_file_size = -1ULL;
        }
 
-       td->mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
+       td->sem = fio_sem_init(FIO_SEM_LOCKED);
 
        td->ts.clat_percentiles = o->clat_percentiles;
        td->ts.lat_percentiles = o->lat_percentiles;
        td->ts.percentile_precision = o->percentile_precision;
        memcpy(td->ts.percentile_list, o->percentile_list, sizeof(o->percentile_list));
+       td->ts.sig_figs = o->sig_figs;
 
        for (i = 0; i < DDIR_RWDIR_CNT; i++) {
                td->ts.clat_stat[i].min_val = ULONG_MAX;
@@ -1449,6 +1495,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                td->ts.bw_stat[i].min_val = ULONG_MAX;
                td->ts.iops_stat[i].min_val = ULONG_MAX;
        }
+       td->ts.sync_stat.min_val = ULONG_MAX;
        td->ddir_seq_nr = o->ddir_seq_nr;
 
        if ((o->stonewall || o->new_group) && prev_group_jobs) {
@@ -1552,7 +1599,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                        p.avg_msec = min(o->log_avg_msec, o->bw_avg_time);
                else
                        o->bw_avg_time = p.avg_msec;
-       
+
                p.hist_msec = o->log_hist_msec;
                p.hist_coarseness = o->log_hist_coarseness;
 
@@ -1583,7 +1630,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                        p.avg_msec = min(o->log_avg_msec, o->iops_avg_time);
                else
                        o->iops_avg_time = p.avg_msec;
-       
+
                p.hist_msec = o->log_hist_msec;
                p.hist_coarseness = o->log_hist_coarseness;
 
@@ -2056,7 +2103,7 @@ static int fill_def_thread(void)
 static void show_debug_categories(void)
 {
 #ifdef FIO_INC_DEBUG
-       struct debug_level *dl = &debug_levels[0];
+       const struct debug_level *dl = &debug_levels[0];
        int curlen, first = 1;
 
        curlen = 0;
@@ -2146,7 +2193,7 @@ static void usage(const char *name)
 }
 
 #ifdef FIO_INC_DEBUG
-struct debug_level debug_levels[] = {
+const struct debug_level debug_levels[] = {
        { .name = "process",
          .help = "Process creation/exit logging",
          .shift = FD_PROCESS,
@@ -2224,7 +2271,7 @@ struct debug_level debug_levels[] = {
 
 static int set_debug(const char *string)
 {
-       struct debug_level *dl;
+       const struct debug_level *dl;
        char *p = (char *) string;
        char *opt;
        int i;
@@ -2504,8 +2551,31 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
                                log_err("fio: failed parsing eta time %s\n", optarg);
                                exit_val = 1;
                                do_exit++;
+                               break;
                        }
                        eta_new_line = t / 1000;
+                       if (!eta_new_line) {
+                               log_err("fio: eta new line time too short\n");
+                               exit_val = 1;
+                               do_exit++;
+                       }
+                       break;
+                       }
+               case 'O': {
+                       long long t = 0;
+
+                       if (check_str_time(optarg, &t, 1)) {
+                               log_err("fio: failed parsing eta interval %s\n", optarg);
+                               exit_val = 1;
+                               do_exit++;
+                               break;
+                       }
+                       eta_interval_msec = t / 1000;
+                       if (eta_interval_msec < DISK_UTIL_MSEC) {
+                               log_err("fio: eta interval time too short (%umsec min)\n", DISK_UTIL_MSEC);
+                               exit_val = 1;
+                               do_exit++;
+                       }
                        break;
                        }
                case 'd':