X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=backend.c;h=4437d196c0d5cdf2b5a9ce34c1982d353e7ea480;hp=68540abb9a2c1bd80c346d311f94646b464e2ff9;hb=b2ee7647ee05604397672f6b7c1a804b07466270;hpb=78d55e721268e2fb9bea707529db89bacf9964ef diff --git a/backend.c b/backend.c index 68540abb..4437d196 100644 --- a/backend.c +++ b/backend.c @@ -56,7 +56,9 @@ #include "lib/tp.h" static pthread_t disk_util_thread; -static struct fio_mutex *disk_thread_mutex; +static pthread_cond_t du_cond; +static pthread_mutex_t du_lock; + static struct fio_mutex *startup_mutex; static struct flist_head *cgroup_list; static char *cgroup_mnt; @@ -87,7 +89,7 @@ static void sig_int(int sig) fio_server_got_signal(sig); else { log_info("\nfio: terminating on signal %d\n", sig); - fflush(stdout); + log_info_flush(); exit_value = 128; } @@ -391,7 +393,7 @@ static int break_on_this_error(struct thread_data *td, enum fio_ddir ddir, * fill_device option is set. */ td_clear_error(td); - td->terminate = 1; + fio_mark_td_terminate(td); return 1; } else { /* @@ -460,7 +462,7 @@ static void do_verify(struct thread_data *td, uint64_t verify_bytes) if (runtime_exceeded(td, &td->tv_cache)) { __update_tv_cache(td); if (runtime_exceeded(td, &td->tv_cache)) { - td->terminate = 1; + fio_mark_td_terminate(td); break; } } @@ -714,7 +716,7 @@ static uint64_t do_io(struct thread_data *td) if (runtime_exceeded(td, &td->tv_cache)) { __update_tv_cache(td); if (runtime_exceeded(td, &td->tv_cache)) { - td->terminate = 1; + fio_mark_td_terminate(td); break; } } @@ -922,7 +924,7 @@ reap: if (td->o.fill_device && td->error == ENOSPC) { td->error = 0; - td->terminate = 1; + fio_mark_td_terminate(td); } if (!td->error) { struct fio_file *f; @@ -1603,6 +1605,13 @@ static int fork_main(int shmid, int offset) return (int) (uintptr_t) ret; } +static void dump_td_info(struct thread_data *td) +{ + log_err("fio: job '%s' hasn't exited in %lu seconds, it appears to " + "be stuck. Doing forceful exit of this job.\n", td->o.name, + (unsigned long) time_since_now(&td->terminate_time)); +} + /* * Run over the job map and reap the threads that have exited, if any. */ @@ -1680,6 +1689,17 @@ static void reap_threads(unsigned int *nr_running, unsigned int *t_rate, } } + /* + * If the job is stuck, do a forceful timeout of it and + * move on. + */ + if (td->terminate && + time_since_now(&td->terminate_time) >= FIO_REAP_TIMEOUT) { + dump_td_info(td); + td_set_runstate(td, TD_REAPED); + goto reaped; + } + /* * thread is not dead, continue */ @@ -1745,7 +1765,7 @@ static void run_threads(void) nr_process > 1 ? "es" : ""); } log_info("\n"); - fflush(stdout); + log_info_flush(); } todo = thread_number; @@ -1952,16 +1972,20 @@ static void run_threads(void) update_io_ticks(); } -void wait_for_disk_thread_exit(void) +static void wait_for_disk_thread_exit(void) { - fio_mutex_down(disk_thread_mutex); + void *ret; + + disk_util_start_exit(); + pthread_cond_signal(&du_cond); + pthread_join(disk_util_thread, &ret); } static void free_disk_util(void) { - disk_util_start_exit(); - wait_for_disk_thread_exit(); disk_util_prune_entries(); + + pthread_cond_destroy(&du_cond); } static void *disk_thread_main(void *data) @@ -1970,17 +1994,30 @@ static void *disk_thread_main(void *data) fio_mutex_up(startup_mutex); - while (threads && !ret) { - usleep(DISK_UTIL_MSEC * 1000); - if (!threads) + while (!ret) { + uint64_t sec = DISK_UTIL_MSEC / 1000; + uint64_t nsec = (DISK_UTIL_MSEC % 1000) * 1000000; + struct timespec ts; + struct timeval tv; + + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec + sec; + ts.tv_nsec = (tv.tv_usec * 1000) + nsec; + if (ts.tv_nsec > 1000000000ULL) { + ts.tv_nsec -= 1000000000ULL; + ts.tv_sec++; + } + + ret = pthread_cond_timedwait(&du_cond, &du_lock, &ts); + if (ret != ETIMEDOUT) break; + ret = update_io_ticks(); if (!is_backend) print_thread_status(); } - fio_mutex_up(disk_thread_mutex); return NULL; } @@ -1990,22 +2027,15 @@ static int create_disk_util_thread(void) setup_disk_util(); - disk_thread_mutex = fio_mutex_init(FIO_MUTEX_LOCKED); + pthread_cond_init(&du_cond, NULL); + pthread_mutex_init(&du_lock, NULL); ret = pthread_create(&disk_util_thread, NULL, disk_thread_main, NULL); if (ret) { - fio_mutex_remove(disk_thread_mutex); log_err("Can't create disk util thread: %s\n", strerror(ret)); return 1; } - ret = pthread_detach(disk_util_thread); - if (ret) { - fio_mutex_remove(disk_thread_mutex); - log_err("Can't detatch disk util thread: %s\n", strerror(ret)); - return 1; - } - dprint(FD_MUTEX, "wait on startup_mutex\n"); fio_mutex_down(startup_mutex); dprint(FD_MUTEX, "done waiting on startup_mutex\n"); @@ -2043,14 +2073,18 @@ int fio_backend(void) set_genesis_time(); stat_init(); create_disk_util_thread(); + create_status_interval_thread(); cgroup_list = smalloc(sizeof(*cgroup_list)); INIT_FLIST_HEAD(cgroup_list); run_threads(); + wait_for_disk_thread_exit(); + wait_for_status_interval_thread_exit(); + if (!fio_abort) { - show_run_stats(); + __show_run_stats(); if (write_bw_log) { int i; @@ -2072,7 +2106,6 @@ int fio_backend(void) sfree(cgroup_mnt); fio_mutex_remove(startup_mutex); - fio_mutex_remove(disk_thread_mutex); stat_exit(); return exit_value; }