Free io_u related structures before killing IO engine
[fio.git] / backend.c
index c31d22af40ac1900d83d73f1c566cefa5cbff705..a71d768d22d89437e4a6cde828c24c36bb28ecbf 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -34,7 +34,9 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <sys/ipc.h>
+#ifndef FIO_NO_HAVE_SHM_H
 #include <sys/shm.h>
+#endif
 #include <sys/mman.h>
 
 #include "fio.h"
@@ -62,11 +64,13 @@ struct io_log *agg_io_log[DDIR_RWDIR_CNT];
 
 int groupid = 0;
 unsigned int thread_number = 0;
+unsigned int stat_number = 0;
 unsigned int nr_process = 0;
 unsigned int nr_thread = 0;
 int shm_id = 0;
 int temp_stall_ts;
 unsigned long done_secs = 0;
+volatile int disk_util_exit = 0;
 
 #define PAGE_ALIGN(buf)        \
        (char *) (((uintptr_t) (buf) + page_mask) & ~page_mask)
@@ -107,6 +111,14 @@ static void set_sig_handlers(void)
        act.sa_flags = SA_RESTART;
        sigaction(SIGTERM, &act, NULL);
 
+/* Windows uses SIGBREAK as a quit signal from other applications */
+#ifdef WIN32
+       memset(&act, 0, sizeof(act));
+       act.sa_handler = sig_int;
+       act.sa_flags = SA_RESTART;
+       sigaction(SIGBREAK, &act, NULL);
+#endif
+
        memset(&act, 0, sizeof(act));
        act.sa_handler = sig_show_status;
        act.sa_flags = SA_RESTART;
@@ -582,7 +594,7 @@ static void do_io(struct thread_data *td)
                int ret2, full;
                enum fio_ddir ddir;
 
-               if (td->terminate)
+               if (td->terminate || td->done)
                        break;
 
                update_tv_cache(td);
@@ -717,7 +729,7 @@ sync_done:
 
                if (ret < 0)
                        break;
-               if (!ddir_rw_sum(bytes_done))
+               if (!ddir_rw_sum(bytes_done) && !(td->io_ops->flags & FIO_NOIO))
                        continue;
 
                if (!in_ramp_time(td) && should_check_rate(td, bytes_done)) {
@@ -791,6 +803,10 @@ static void cleanup_io_u(struct thread_data *td)
                io_u = flist_entry(entry, struct io_u, list);
 
                flist_del(&io_u->list);
+
+               if (td->io_ops->io_u_free)
+                       td->io_ops->io_u_free(td, io_u);
+
                fio_memfree(io_u, sizeof(*io_u));
        }
 
@@ -873,6 +889,16 @@ static int init_io_u(struct thread_data *td)
                io_u->index = i;
                io_u->flags = IO_U_F_FREE;
                flist_add(&io_u->list, &td->io_u_freelist);
+
+               if (td->io_ops->io_u_init) {
+                       int ret = td->io_ops->io_u_init(td, io_u);
+
+                       if (ret) {
+                               log_err("fio: failed to init engine data: %d\n", ret);
+                               return 1;
+                       }
+               }
+
                p += max_bs;
        }
 
@@ -1043,6 +1069,49 @@ static void *thread_main(void *data)
                goto err;
        }
 
+#ifdef FIO_HAVE_LIBNUMA
+       /* numa node setup */
+       if (td->o.numa_cpumask_set || td->o.numa_memmask_set) {
+               int ret;
+
+               if (numa_available() < 0) {
+                       td_verror(td, errno, "Does not support NUMA API\n");
+                       goto err;
+               }
+
+               if (td->o.numa_cpumask_set) {
+                       ret = numa_run_on_node_mask(td->o.numa_cpunodesmask);
+                       if (ret == -1) {
+                               td_verror(td, errno, \
+                                       "numa_run_on_node_mask failed\n");
+                               goto err;
+                       }
+               }
+
+               if (td->o.numa_memmask_set) {
+
+                       switch (td->o.numa_mem_mode) {
+                       case MPOL_INTERLEAVE:
+                               numa_set_interleave_mask(td->o.numa_memnodesmask);
+                               break;
+                       case MPOL_BIND:
+                               numa_set_membind(td->o.numa_memnodesmask);
+                               break;
+                       case MPOL_LOCAL:
+                               numa_set_localalloc();
+                               break;
+                       case MPOL_PREFERRED:
+                               numa_set_preferred(td->o.numa_mem_prefer_node);
+                               break;
+                       case MPOL_DEFAULT:
+                       default:
+                               break;
+                       }
+
+               }
+       }
+#endif
+
        /*
         * May alter parameters that init_io_u() will use, so we need to
         * do this first.
@@ -1218,8 +1287,8 @@ err:
                verify_async_exit(td);
 
        close_and_free_files(td);
-       close_ioengine(td);
        cleanup_io_u(td);
+       close_ioengine(td);
        cgroup_shutdown(td, &cgroup_mnt);
 
        if (td->o.cpumask_set) {
@@ -1330,7 +1399,7 @@ static void reap_threads(unsigned int *nr_running, unsigned int *t_rate,
                        if (WIFSIGNALED(status)) {
                                int sig = WTERMSIG(status);
 
-                               if (sig != SIGTERM)
+                               if (sig != SIGTERM && sig != SIGUSR2)
                                        log_err("fio: pid=%d, got signal=%d\n",
                                                        (int) td->pid, sig);
                                td->sig = sig;
@@ -1610,6 +1679,13 @@ void wait_for_disk_thread_exit(void)
        fio_mutex_down(disk_thread_mutex);
 }
 
+static void free_disk_util(void)
+{
+       disk_util_start_exit();
+       wait_for_disk_thread_exit();
+       disk_util_prune_entries();
+}
+
 static void *disk_thread_main(void *data)
 {
        int ret = 0;