X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=backend.c;h=3a1df299fd80f920ee97d8f1ecb79b525726a838;hp=dcc6fba06fdb58636555cdd1db13d5113cab9b21;hb=73cfb8a7da365c37253662477edb54ecc19575df;hpb=80666bece308842c36132245e4cbbe9eb0bc506b diff --git a/backend.c b/backend.c index dcc6fba0..3a1df299 100644 --- a/backend.c +++ b/backend.c @@ -60,13 +60,14 @@ static volatile int fio_abort; static unsigned int nr_process = 0; static unsigned int nr_thread = 0; -struct io_log *agg_io_log[2]; +struct io_log *agg_io_log[DDIR_RWDIR_CNT]; int groupid = 0; unsigned int thread_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) @@ -208,10 +209,12 @@ static int check_min_rate(struct thread_data *td, struct timeval *now, { int ret = 0; - if (bytes_done[0]) - ret |= __check_min_rate(td, now, 0); - if (bytes_done[1]) - ret |= __check_min_rate(td, now, 1); + if (bytes_done[DDIR_READ]) + ret |= __check_min_rate(td, now, DDIR_READ); + if (bytes_done[DDIR_WRITE]) + ret |= __check_min_rate(td, now, DDIR_WRITE); + if (bytes_done[DDIR_TRIM]) + ret |= __check_min_rate(td, now, DDIR_TRIM); return ret; } @@ -335,19 +338,19 @@ 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)) { - /* - * Continue with the I/Os in case of + if (td_non_fatal_error(td, eb, err)) { + /* + * Continue with the I/Os in case of * a non fatal error. */ update_error_count(td, err); @@ -545,11 +548,13 @@ static int io_bytes_exceeded(struct thread_data *td) unsigned long long bytes; if (td_rw(td)) - bytes = td->this_io_bytes[0] + td->this_io_bytes[1]; + bytes = td->this_io_bytes[DDIR_READ] + td->this_io_bytes[DDIR_WRITE]; else if (td_write(td)) - bytes = td->this_io_bytes[1]; + bytes = td->this_io_bytes[DDIR_WRITE]; + else if (td_read(td)) + bytes = td->this_io_bytes[DDIR_READ]; else - bytes = td->this_io_bytes[0]; + bytes = td->this_io_bytes[DDIR_TRIM]; return bytes >= td->o.size; } @@ -572,7 +577,7 @@ static void do_io(struct thread_data *td) (!flist_empty(&td->trim_list)) || !io_bytes_exceeded(td) || td->o.time_based) { struct timeval comp_time; - unsigned long bytes_done[2] = { 0, 0 }; + unsigned long bytes_done[DDIR_RWDIR_CNT] = { 0, 0, 0 }; int min_evts = 0; struct io_u *io_u; int ret2, full; @@ -649,8 +654,9 @@ static void do_io(struct thread_data *td) requeue_io_u(td, &io_u); } else { sync_done: - if (__should_check_rate(td, 0) || - __should_check_rate(td, 1)) + if (__should_check_rate(td, DDIR_READ) || + __should_check_rate(td, DDIR_WRITE) || + __should_check_rate(td, DDIR_TRIM)) fio_gettime(&comp_time, NULL); ret = io_u_sync_complete(td, io_u, bytes_done); @@ -697,8 +703,9 @@ sync_done: if (full && !min_evts) min_evts = 1; - if (__should_check_rate(td, 0) || - __should_check_rate(td, 1)) + if (__should_check_rate(td, DDIR_READ) || + __should_check_rate(td, DDIR_WRITE) || + __should_check_rate(td, DDIR_TRIM)) fio_gettime(&comp_time, NULL); do { @@ -711,7 +718,7 @@ sync_done: if (ret < 0) break; - if (!(bytes_done[0] + bytes_done[1])) + if (!ddir_rw_sum(bytes_done)) continue; if (!in_ramp_time(td) && should_check_rate(td, bytes_done)) { @@ -726,7 +733,7 @@ sync_done: if (td->o.thinktime) { unsigned long long b; - b = td->io_blocks[0] + td->io_blocks[1]; + b = ddir_rw_sum(td->io_blocks); if (!(b % td->o.thinktime_blocks)) { int left; @@ -772,7 +779,7 @@ sync_done: /* * stop job if we failed doing any IO */ - if ((td->this_io_bytes[0] + td->this_io_bytes[1]) == 0) + if (!ddir_rw_sum(td->this_io_bytes)) td->done = 1; } @@ -796,14 +803,19 @@ 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; max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]); + max_bs = max(td->o.max_bs[DDIR_TRIM], max_bs); min_write = td->o.min_bs[DDIR_WRITE]; 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; @@ -816,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 || @@ -844,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); @@ -926,8 +938,6 @@ static int switch_ioscheduler(struct thread_data *td) static int keep_running(struct thread_data *td) { - unsigned long long io_done; - if (td->done) return 0; if (td->o.time_based) @@ -937,9 +947,7 @@ static int keep_running(struct thread_data *td) return 1; } - io_done = td->io_bytes[DDIR_READ] + td->io_bytes[DDIR_WRITE] - + td->io_skip_bytes; - if (io_done < td->o.size) + if (ddir_rw_sum(td->io_bytes) < td->o.size) return 1; return 0; @@ -1110,10 +1118,13 @@ static void *thread_main(void *data) memcpy(&td->iops_sample_time, &td->start, sizeof(td->start)); memcpy(&td->tv_cache, &td->start, sizeof(td->start)); - if (td->o.ratemin[0] || td->o.ratemin[1]) { - memcpy(&td->lastrate[0], &td->bw_sample_time, + if (td->o.ratemin[DDIR_READ] || td->o.ratemin[DDIR_WRITE] || + td->o.ratemin[DDIR_TRIM]) { + memcpy(&td->lastrate[DDIR_READ], &td->bw_sample_time, + sizeof(td->bw_sample_time)); + memcpy(&td->lastrate[DDIR_WRITE], &td->bw_sample_time, sizeof(td->bw_sample_time)); - memcpy(&td->lastrate[1], &td->bw_sample_time, + memcpy(&td->lastrate[DDIR_TRIM], &td->bw_sample_time, sizeof(td->bw_sample_time)); } @@ -1134,6 +1145,10 @@ static void *thread_main(void *data) elapsed = utime_since_now(&td->start); td->ts.runtime[DDIR_WRITE] += elapsed; } + if (td_trim(td) && td->io_bytes[DDIR_TRIM]) { + elapsed = utime_since_now(&td->start); + td->ts.runtime[DDIR_TRIM] += elapsed; + } if (td->error || td->terminate) break; @@ -1156,11 +1171,13 @@ static void *thread_main(void *data) } update_rusage_stat(td); - td->ts.runtime[0] = (td->ts.runtime[0] + 999) / 1000; - td->ts.runtime[1] = (td->ts.runtime[1] + 999) / 1000; + td->ts.runtime[DDIR_READ] = (td->ts.runtime[DDIR_READ] + 999) / 1000; + td->ts.runtime[DDIR_WRITE] = (td->ts.runtime[DDIR_WRITE] + 999) / 1000; + td->ts.runtime[DDIR_TRIM] = (td->ts.runtime[DDIR_TRIM] + 999) / 1000; td->ts.total_run_time = mtime_since_now(&td->epoch); - td->ts.io_bytes[0] = td->io_bytes[0]; - td->ts.io_bytes[1] = td->io_bytes[1]; + td->ts.io_bytes[DDIR_READ] = td->io_bytes[DDIR_READ]; + 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); @@ -1352,8 +1369,8 @@ static void reap_threads(unsigned int *nr_running, unsigned int *t_rate, continue; reaped: (*nr_running)--; - (*m_rate) -= (td->o.ratemin[0] + td->o.ratemin[1]); - (*t_rate) -= (td->o.rate[0] + td->o.rate[1]); + (*m_rate) -= ddir_rw_sum(td->o.ratemin); + (*t_rate) -= ddir_rw_sum(td->o.rate); if (!td->pid) pending--; @@ -1389,7 +1406,7 @@ static void run_threads(void) nr_process++; } - if (!terse_output) { + if (output_format == FIO_OUTPUT_NORMAL) { log_info("Starting "); if (nr_thread) log_info("%d thread%s", nr_thread, @@ -1580,8 +1597,8 @@ static void run_threads(void) td_set_runstate(td, TD_RUNNING); nr_running++; nr_started--; - m_rate += td->o.ratemin[0] + td->o.ratemin[1]; - t_rate += td->o.rate[0] + td->o.rate[1]; + m_rate += ddir_rw_sum(td->o.ratemin); + t_rate += ddir_rw_sum(td->o.rate); todo--; fio_mutex_up(td->mutex); } @@ -1605,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; @@ -1631,7 +1655,7 @@ static int create_disk_util_thread(void) setup_disk_util(); - disk_thread_mutex = fio_mutex_init(0); + disk_thread_mutex = fio_mutex_init(FIO_MUTEX_LOCKED); ret = pthread_create(&disk_util_thread, NULL, disk_thread_main, NULL); if (ret) { @@ -1670,12 +1694,13 @@ int fio_backend(void) if (write_bw_log) { 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(0); + startup_mutex = fio_mutex_init(FIO_MUTEX_LOCKED); if (startup_mutex == NULL) return 1; - writeout_mutex = fio_mutex_init(1); + writeout_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED); if (writeout_mutex == NULL) return 1; @@ -1693,6 +1718,8 @@ int fio_backend(void) __finish_log(agg_io_log[DDIR_READ], "agg-read_bw.log"); __finish_log(agg_io_log[DDIR_WRITE], "agg-write_bw.log"); + __finish_log(agg_io_log[DDIR_TRIM], + "agg-write_bw.log"); } }