X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=fio.c;h=ead118ec35a0d02572a5366f4fe065a904c0cf05;hp=d8c143332823bf2c488ef0799951c8ce70c71fe3;hb=d87612ac34a3cf1ac94a9ddc0cada672b6541b3c;hpb=7a93ab190e5fea78edb21affeb0189a9d61a2cd8 diff --git a/fio.c b/fio.c index d8c14333..ead118ec 100644 --- a/fio.c +++ b/fio.c @@ -614,7 +614,6 @@ static void fill_io_buf(struct thread_data *td, struct io_u *io_u, int max_bs) static int init_io_u(struct thread_data *td) { - unsigned long long buf_size; struct io_u *io_u; unsigned int max_bs; int i, max_units; @@ -626,25 +625,23 @@ static int init_io_u(struct thread_data *td) max_units = td->o.iodepth; max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]); - buf_size = (unsigned long long) max_bs * (unsigned long long) max_units; - buf_size += page_mask; - if (buf_size != (size_t) buf_size) { - log_err("fio: IO memory too large. Reduce max_bs or iodepth\n"); - return 1; - } - - td->orig_buffer_size = buf_size; + td->orig_buffer_size = (unsigned long long) max_bs * (unsigned long long) max_units; if (td->o.mem_type == MEM_SHMHUGE || td->o.mem_type == MEM_MMAPHUGE) td->orig_buffer_size = (td->orig_buffer_size + td->o.hugepage_size - 1) & ~(td->o.hugepage_size - 1); - else if (td->orig_buffer_size & page_mask) - td->orig_buffer_size = (td->orig_buffer_size + page_mask) & ~page_mask; + + if (td->orig_buffer_size != (size_t) td->orig_buffer_size) { + log_err("fio: IO memory too large. Reduce max_bs or iodepth\n"); + return 1; + } if (allocate_io_mem(td)) return 1; p = ALIGN(td->orig_buffer); for (i = 0; i < max_units; i++) { + if (td->terminate) + return 1; io_u = malloc(sizeof(*io_u)); memset(io_u, 0, sizeof(*io_u)); INIT_LIST_HEAD(&io_u->list); @@ -719,6 +716,24 @@ static int switch_ioscheduler(struct thread_data *td) return 0; } +static int keep_running(struct thread_data *td) +{ + unsigned long long io_done; + + if (td->o.time_based) + return 1; + if (td->o.loops) { + td->o.loops--; + return 1; + } + + io_done = td->io_bytes[DDIR_READ] + td->io_bytes[DDIR_WRITE]; + if (io_done < td->o.size) + return 1; + + return 0; +} + static int clear_io_state(struct thread_data *td) { struct fio_file *f; @@ -734,11 +749,14 @@ static int clear_io_state(struct thread_data *td) td->last_was_sync = 0; + td->nr_done_files = 0; + for_each_file(td, f, i) td_io_close_file(td, f); ret = 0; for_each_file(td, f, i) { + f->flags &= ~FIO_FILE_DONE; ret = td_io_open_file(td, f); if (ret) break; @@ -770,41 +788,45 @@ static void *thread_main(void *data) INIT_LIST_HEAD(&td->io_hist_list); td->io_hist_tree = RB_ROOT; + td_set_runstate(td, TD_INITIALIZED); + fio_sem_up(startup_sem); + fio_sem_down(td->mutex); + + /* + * the ->mutex semaphore is now no longer used, close it to avoid + * eating a file descriptor + */ + fio_sem_remove(td->mutex); + + /* + * May alter parameters that init_io_u() will use, so we need to + * do this first. + */ + if (init_iolog(td)) + goto err; + if (init_io_u(td)) - goto err_sem; + goto err; - if (fio_setaffinity(td) == -1) { + if (td->o.cpumask_set && fio_setaffinity(td) == -1) { td_verror(td, errno, "cpu_set_affinity"); - goto err_sem; + goto err; } - if (init_iolog(td)) - goto err_sem; - if (td->ioprio) { if (ioprio_set(IOPRIO_WHO_PROCESS, 0, td->ioprio) == -1) { td_verror(td, errno, "ioprio_set"); - goto err_sem; + goto err; } } if (nice(td->o.nice) == -1) { td_verror(td, errno, "nice"); - goto err_sem; + goto err; } if (td->o.ioscheduler && switch_ioscheduler(td)) - goto err_sem; - - td_set_runstate(td, TD_INITIALIZED); - fio_sem_up(startup_sem); - fio_sem_down(td->mutex); - - /* - * the ->mutex semaphore is now no longer used, close it to avoid - * eating a file descriptor - */ - fio_sem_remove(td->mutex); + goto err; if (!td->o.create_serialize && setup_files(td)) goto err; @@ -829,7 +851,7 @@ static void *thread_main(void *data) runtime[0] = runtime[1] = 0; clear_state = 0; - while (td->o.time_based || td->o.loops--) { + while (keep_running(td)) { fio_gettime(&td->start, NULL); memcpy(&td->ts.stat_sample_time, &td->start, sizeof(td->start)); @@ -913,9 +935,6 @@ err: options_mem_free(td); td_set_runstate(td, TD_EXITED); return (void *) (unsigned long) td->error; -err_sem: - fio_sem_up(startup_sem); - goto err; } /*