Set affinity before doing buffer and io_u allocs
[fio.git] / fio.c
diff --git a/fio.c b/fio.c
index a737a310df821b62978fc420a36968d7c64c8324..81854818d6bd81ae3cd503a8eb4e4661d99bfc93 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -102,7 +102,7 @@ static void terminate_threads(int group_id)
                        /*
                         * if the thread is running, just let it exit
                         */
-                       if (td->runstate < TD_RUNNING)
+                       if (td->runstate < TD_RAMP)
                                kill(td->pid, SIGTERM);
                        else {
                                struct ioengine_ops *ops = td->io_ops;
@@ -114,18 +114,12 @@ static void terminate_threads(int group_id)
        }
 }
 
-/*
- * Happens on thread runs with ctrl-c, ignore our own SIGQUIT
- */
-static void sig_quit(int sig)
-{
-}
-
 static void sig_int(int sig)
 {
        if (threads) {
                log_info("\nfio: terminating on signal %d\n", sig);
                fflush(stdout);
+               exit_value = 128;
                terminate_threads(TERMINATE_ALL);
        }
 }
@@ -177,7 +171,7 @@ static void set_sig_handlers(void)
        sigaction(SIGINT, &act, NULL);
 
        memset(&act, 0, sizeof(act));
-       act.sa_handler = sig_quit;
+       act.sa_handler = sig_int;
        act.sa_flags = SA_RESTART;
        sigaction(SIGTERM, &act, NULL);
 }
@@ -186,7 +180,7 @@ static void set_sig_handlers(void)
  * Check if we are above the minimum rate given.
  */
 static int __check_min_rate(struct thread_data *td, struct timeval *now,
-                           enum td_ddir ddir)
+                           enum fio_ddir ddir)
 {
        unsigned long long bytes = 0;
        unsigned long iops = 0;
@@ -378,10 +372,15 @@ requeue:
        return 0;
 }
 
+static inline void __update_tv_cache(struct thread_data *td)
+{
+       fio_gettime(&td->tv_cache, NULL);
+}
+
 static inline void update_tv_cache(struct thread_data *td)
 {
        if ((++td->tv_cache_nr & td->tv_cache_mask) == td->tv_cache_mask)
-               fio_gettime(&td->tv_cache, NULL);
+               __update_tv_cache(td);
 }
 
 static int break_on_this_error(struct thread_data *td, int *retptr)
@@ -467,8 +466,11 @@ static void do_verify(struct thread_data *td)
                update_tv_cache(td);
 
                if (runtime_exceeded(td, &td->tv_cache)) {
-                       td->terminate = 1;
-                       break;
+                       __update_tv_cache(td);
+                       if (runtime_exceeded(td, &td->tv_cache)) {
+                               td->terminate = 1;
+                               break;
+                       }
                }
 
                io_u = __get_io_u(td);
@@ -613,8 +615,11 @@ static void do_io(struct thread_data *td)
                update_tv_cache(td);
 
                if (runtime_exceeded(td, &td->tv_cache)) {
-                       td->terminate = 1;
-                       break;
+                       __update_tv_cache(td);
+                       if (runtime_exceeded(td, &td->tv_cache)) {
+                               td->terminate = 1;
+                               break;
+                       }
                }
 
                io_u = get_io_u(td);
@@ -766,8 +771,11 @@ sync_done:
                struct fio_file *f;
 
                i = td->cur_depth;
-               if (i)
+               if (i) {
                        ret = io_u_queued_complete(td, i, NULL);
+                       if (td->o.fill_device && td->error == ENOSPC)
+                               td->error = 0;
+               }
 
                if (should_fsync(td) && td->o.end_fsync) {
                        td_set_runstate(td, TD_FSYNCING);
@@ -970,11 +978,6 @@ static void reset_io_counters(struct thread_data *td)
         */
        if (td->o.time_based || td->o.loops)
                td->nr_done_files = 0;
-
-       /*
-        * Set the same seed to get repeatable runs
-        */
-       td_fill_rand_seeds(td);
 }
 
 void reset_all_stats(struct thread_data *td)
@@ -1008,6 +1011,11 @@ static void clear_io_state(struct thread_data *td)
        close_files(td);
        for_each_file(td, f, i)
                fio_file_clear_done(f);
+
+       /*
+        * Set the same seed to get repeatable runs
+        */
+       td_fill_rand_seeds(td);
 }
 
 static int exec_string(const char *string)
@@ -1084,6 +1092,22 @@ static void *thread_main(void *data)
                goto err;
        }
 
+       /*
+        * If we have a gettimeofday() thread, make sure we exclude that
+        * thread from this job
+        */
+       if (td->o.gtod_cpu)
+               fio_cpu_clear(&td->o.cpumask, td->o.gtod_cpu);
+
+       /*
+        * Set affinity first, in case it has an impact on the memory
+        * allocations.
+        */
+       if (td->o.cpumask_set && fio_setaffinity(td->pid, td->o.cpumask) == -1) {
+               td_verror(td, errno, "cpu_set_affinity");
+               goto err;
+       }
+
        /*
         * May alter parameters that init_io_u() will use, so we need to
         * do this first.
@@ -1097,23 +1121,6 @@ static void *thread_main(void *data)
        if (td->o.verify_async && verify_async_init(td))
                goto err;
 
-       if (td->o.cpumask_set && fio_setaffinity(td->pid, td->o.cpumask) == -1) {
-               td_verror(td, errno, "cpu_set_affinity");
-               goto err;
-       }
-
-       /*
-        * If we have a gettimeofday() thread, make sure we exclude that
-        * thread from this job
-        */
-       if (td->o.gtod_cpu) {
-               fio_cpu_clear(&td->o.cpumask, td->o.gtod_cpu);
-               if (fio_setaffinity(td->pid, td->o.cpumask) == -1) {
-                       td_verror(td, errno, "cpu_set_affinity");
-                       goto err;
-               }
-       }
-
        if (td->ioprio_set) {
                if (ioprio_set(IOPRIO_WHO_PROCESS, 0, td->ioprio) == -1) {
                        td_verror(td, errno, "ioprio_set");
@@ -1518,7 +1525,7 @@ static void run_threads(void)
        set_genesis_time();
 
        while (todo) {
-               struct thread_data *map[MAX_JOBS];
+               struct thread_data *map[REAL_MAX_JOBS];
                struct timeval this_start;
                int this_jobs = 0, left;