Merge branch 'master' into gfio
[fio.git] / backend.c
index 9b0d7918337c0b0c645e1911c33ad396319df0f3..3a1df299fd80f920ee97d8f1ecb79b525726a838 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -57,16 +57,17 @@ static struct flist_head *cgroup_list;
 static char *cgroup_mnt;
 static int exit_value;
 static volatile int fio_abort;
+static unsigned int nr_process = 0;
+static unsigned int nr_thread = 0;
 
 struct io_log *agg_io_log[DDIR_RWDIR_CNT];
 
 int groupid = 0;
 unsigned int thread_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)
@@ -337,17 +338,17 @@ static int break_on_this_error(struct thread_data *td, enum fio_ddir ddir,
        int ret = *retptr;
 
        if (ret < 0 || td->error) {
-               int err;
+               int err = td->error;
+               enum error_type_bit eb;
 
                if (ret < 0)
                        err = -ret;
-               else
-                       err = td->error;
 
-               if (!(td->o.continue_on_error & td_error_type(ddir, err)))
+               eb = td_error_type(ddir, err);
+               if (!(td->o.continue_on_error & (1 << eb)))
                        return 1;
 
-               if (td_non_fatal_error(err)) {
+               if (td_non_fatal_error(td, eb, err)) {
                        /*
                         * Continue with the I/Os in case of
                         * a non fatal error.
@@ -802,6 +803,7 @@ static int init_io_u(struct thread_data *td)
        struct io_u *io_u;
        unsigned int max_bs, min_write;
        int cl_align, i, max_units;
+       int data_xfer = 1;
        char *p;
 
        max_units = td->o.iodepth;
@@ -811,6 +813,9 @@ static int init_io_u(struct thread_data *td)
        td->orig_buffer_size = (unsigned long long) max_bs
                                        * (unsigned long long) max_units;
 
+       if ((td->io_ops->flags & FIO_NOIO) || !(td_read(td) || td_write(td)))
+               data_xfer = 0;
+
        if (td->o.mem_type == MEM_SHMHUGE || td->o.mem_type == MEM_MMAPHUGE) {
                unsigned long bs;
 
@@ -823,7 +828,7 @@ static int init_io_u(struct thread_data *td)
                return 1;
        }
 
-       if (allocate_io_mem(td))
+       if (data_xfer && allocate_io_mem(td))
                return 1;
 
        if (td->o.odirect || td->o.mem_align ||
@@ -851,7 +856,7 @@ static int init_io_u(struct thread_data *td)
                INIT_FLIST_HEAD(&io_u->list);
                dprint(FD_MEM, "io_u alloc %p, index %u\n", io_u, i);
 
-               if (!(td->io_ops->flags & FIO_NOIO)) {
+               if (data_xfer) {
                        io_u->buf = p;
                        dprint(FD_MEM, "io_u %p, mem %p\n", io_u, io_u->buf);
 
@@ -972,10 +977,12 @@ static void *thread_main(void *data)
 {
        unsigned long long elapsed;
        struct thread_data *td = data;
+       struct thread_options *o = &td->o;
        pthread_condattr_t attr;
        int clear_state;
+       int ret;
 
-       if (!td->o.use_thread) {
+       if (!o->use_thread) {
                setsid();
                td->pid = getpid();
        } else
@@ -983,6 +990,9 @@ static void *thread_main(void *data)
 
        dprint(FD_PROCESS, "jobs pid=%d started\n", (int) td->pid);
 
+       if (is_backend)
+               fio_server_send_start(td);
+
        INIT_FLIST_HEAD(&td->io_u_freelist);
        INIT_FLIST_HEAD(&td->io_u_busylist);
        INIT_FLIST_HEAD(&td->io_u_requeues);
@@ -1009,16 +1019,17 @@ static void *thread_main(void *data)
         * eating a file descriptor
         */
        fio_mutex_remove(td->mutex);
+       td->mutex = NULL;
 
        /*
         * A new gid requires privilege, so we need to do this before setting
         * the uid.
         */
-       if (td->o.gid != -1U && setgid(td->o.gid)) {
+       if (o->gid != -1U && setgid(o->gid)) {
                td_verror(td, errno, "setgid");
                goto err;
        }
-       if (td->o.uid != -1U && setuid(td->o.uid)) {
+       if (o->uid != -1U && setuid(o->uid)) {
                td_verror(td, errno, "setuid");
                goto err;
        }
@@ -1027,18 +1038,24 @@ static void *thread_main(void *data)
         * 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 (o->gtod_cpu)
+               fio_cpu_clear(&o->cpumask, 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;
+       if (o->cpumask_set) {
+               ret = fio_setaffinity(td->pid, o->cpumask);
+               if (ret == -1) {
+                       td_verror(td, errno, "cpu_set_affinity");
+                       goto err;
+               }
        }
 
+       if (fio_pin_memory(td))
+               goto err;
+
        /*
         * May alter parameters that init_io_u() will use, so we need to
         * do this first.
@@ -1049,11 +1066,12 @@ static void *thread_main(void *data)
        if (init_io_u(td))
                goto err;
 
-       if (td->o.verify_async && verify_async_init(td))
+       if (o->verify_async && verify_async_init(td))
                goto err;
 
-       if (td->ioprio_set) {
-               if (ioprio_set(IOPRIO_WHO_PROCESS, 0, td->ioprio) == -1) {
+       if (o->ioprio) {
+               ret = ioprio_set(IOPRIO_WHO_PROCESS, 0, o->ioprio_class, o->ioprio);
+               if (ret == -1) {
                        td_verror(td, errno, "ioprio_set");
                        goto err;
                }
@@ -1063,15 +1081,15 @@ static void *thread_main(void *data)
                goto err;
 
        errno = 0;
-       if (nice(td->o.nice) == -1 && errno != 0) {
+       if (nice(o->nice) == -1 && errno != 0) {
                td_verror(td, errno, "nice");
                goto err;
        }
 
-       if (td->o.ioscheduler && switch_ioscheduler(td))
+       if (o->ioscheduler && switch_ioscheduler(td))
                goto err;
 
-       if (!td->o.create_serialize && setup_files(td))
+       if (!o->create_serialize && setup_files(td))
                goto err;
 
        if (td_io_init(td))
@@ -1080,16 +1098,16 @@ static void *thread_main(void *data)
        if (init_random_map(td))
                goto err;
 
-       if (td->o.exec_prerun) {
-               if (exec_string(td->o.exec_prerun))
-                       goto err;
-       }
+       if (o->exec_prerun && exec_string(o->exec_prerun))
+               goto err;
 
-       if (td->o.pre_read) {
+       if (o->pre_read) {
                if (pre_read_files(td) < 0)
                        goto err;
        }
 
+       fio_verify_init(td);
+
        fio_gettime(&td->epoch, NULL);
        getrusage(RUSAGE_SELF, &td->ru_start);
 
@@ -1161,6 +1179,8 @@ static void *thread_main(void *data)
        td->ts.io_bytes[DDIR_WRITE] = td->io_bytes[DDIR_WRITE];
        td->ts.io_bytes[DDIR_TRIM] = td->io_bytes[DDIR_TRIM];
 
+       fio_unpin_memory(td);
+
        fio_mutex_down(writeout_mutex);
        if (td->bw_log) {
                if (td->o.bw_log_file) {
@@ -1218,8 +1238,8 @@ err:
        cleanup_io_u(td);
        cgroup_shutdown(td, &cgroup_mnt);
 
-       if (td->o.cpumask_set) {
-               int ret = fio_cpuset_exit(&td->o.cpumask);
+       if (o->cpumask_set) {
+               int ret = fio_cpuset_exit(&o->cpumask);
 
                td_verror(td, ret, "fio_cpuset_exit");
        }
@@ -1373,15 +1393,20 @@ static void run_threads(void)
        unsigned long spent;
        unsigned int i, todo, nr_running, m_rate, t_rate, nr_started;
 
-       if (fio_pin_memory())
-               return;
-
        if (fio_gtod_offload && fio_start_gtod_thread())
                return;
 
        set_sig_handlers();
 
-       if (!terse_output) {
+       nr_thread = nr_process = 0;
+       for_each_td(td, i) {
+               if (td->o.use_thread)
+                       nr_thread++;
+               else
+                       nr_process++;
+       }
+
+       if (output_format == FIO_OUTPUT_NORMAL) {
                log_info("Starting ");
                if (nr_thread)
                        log_info("%d thread%s", nr_thread,
@@ -1580,25 +1605,16 @@ static void run_threads(void)
 
                reap_threads(&nr_running, &t_rate, &m_rate);
 
-               if (todo) {
-                       if (is_backend)
-                               fio_server_idle_loop();
-                       else
-                               usleep(100000);
-               }
+               if (todo)
+                       usleep(100000);
        }
 
        while (nr_running) {
                reap_threads(&nr_running, &t_rate, &m_rate);
-
-               if (is_backend)
-                       fio_server_idle_loop();
-               else
-                       usleep(10000);
+               usleep(10000);
        }
 
        update_io_ticks();
-       fio_unpin_memory();
 }
 
 void wait_for_disk_thread_exit(void)
@@ -1606,6 +1622,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;
@@ -1669,9 +1692,9 @@ int fio_backend(void)
                return 0;
 
        if (write_bw_log) {
-               setup_log(&agg_io_log[DDIR_READ], 0);
-               setup_log(&agg_io_log[DDIR_WRITE], 0);
-               setup_log(&agg_io_log[DDIR_TRIM], 0);
+               setup_log(&agg_io_log[DDIR_READ], 0, IO_LOG_TYPE_BW);
+               setup_log(&agg_io_log[DDIR_WRITE], 0, IO_LOG_TYPE_BW);
+               setup_log(&agg_io_log[DDIR_TRIM], 0, IO_LOG_TYPE_BW);
        }
 
        startup_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);