X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;ds=sidebyside;f=backend.c;h=8f16a165c77edfc76de4bf3056402c0167c4f3fa;hb=92a0daf8163eaa8d117d1e6e4fdc11a8dddac2d2;hp=39d13a330581e91974c4f04b36f187b149ff180b;hpb=8b28bd41375930664a0ff9ff9b101a88ac416ac5;p=fio.git diff --git a/backend.c b/backend.c index 39d13a33..8f16a165 100644 --- a/backend.c +++ b/backend.c @@ -34,7 +34,9 @@ #include #include #include +#ifndef FIO_NO_HAVE_SHM_H #include +#endif #include #include "fio.h" @@ -57,16 +59,18 @@ 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; +unsigned int stat_number = 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; @@ -410,6 +422,7 @@ static void do_verify(struct thread_data *td) io_u = NULL; while (!td->terminate) { + enum fio_ddir ddir; int ret2, full; update_tv_cache(td); @@ -444,6 +457,8 @@ static void do_verify(struct thread_data *td) else io_u->end_io = verify_io_u; + ddir = io_u->ddir; + ret = td_io_queue(td, io_u); switch (ret) { case FIO_Q_COMPLETED: @@ -495,7 +510,7 @@ sync_done: break; } - if (break_on_this_error(td, io_u->ddir, &ret)) + if (break_on_this_error(td, ddir, &ret)) break; /* @@ -582,7 +597,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 +732,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 +806,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)); } @@ -802,6 +821,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 +831,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 +846,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 +874,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); @@ -869,6 +892,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; } @@ -972,17 +1005,24 @@ 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 td->pid = gettid(); + fio_local_clock_init(td->o.use_thread); + 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 +1049,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,17 +1068,66 @@ 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"); + 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; + +#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 @@ -1049,11 +1139,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 +1154,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 +1171,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 +1252,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) { @@ -1214,12 +1307,12 @@ 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) { - 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"); } @@ -1326,7 +1419,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; @@ -1373,14 +1466,19 @@ 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(); + 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) @@ -1580,25 +1678,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 +1695,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 +1765,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);