From: Jens Axboe Date: Fri, 26 Apr 2013 23:05:57 +0000 (-0600) Subject: Ensure that stat outputs are serialized X-Git-Tag: fio-2.1~8 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=cef9175e52e8a240117b9f45b228fdaa0f1c0572;hp=fdd5f15f8231e8c91c4deff22e630a34addd0fef Ensure that stat outputs are serialized Two issues: - We don't want potentially two stat outputs running at the same time. This could potentially happen if USR1 or interval stats race with the thread exit. - We could potentially crash if the interval or USR1 signaled stat output trigger when fio is tearing down. Let the main thread wait for any in-progress output in that case. Signed-off-by: Jens Axboe --- diff --git a/backend.c b/backend.c index 4d4e8efd..89ffee12 100644 --- a/backend.c +++ b/backend.c @@ -1895,6 +1895,7 @@ int fio_backend(void) return 1; set_genesis_time(); + stat_init(); create_disk_util_thread(); cgroup_list = smalloc(sizeof(*cgroup_list)); @@ -1924,5 +1925,6 @@ int fio_backend(void) fio_mutex_remove(startup_mutex); fio_mutex_remove(writeout_mutex); fio_mutex_remove(disk_thread_mutex); + stat_exit(); return exit_value; } diff --git a/stat.c b/stat.c index 03a45fc7..b3861887 100644 --- a/stat.c +++ b/stat.c @@ -14,6 +14,8 @@ #include "lib/getrusage.h" #include "idletime.h" +static struct fio_mutex *stat_mutex; + void update_rusage_stat(struct thread_data *td) { struct thread_stat *ts = &td->ts; @@ -1141,7 +1143,7 @@ void init_thread_stat(struct thread_stat *ts) ts->groupid = -1; } -void show_run_stats(void) +static void __show_run_stats(void) { struct group_run_stats *runstats, *rs; struct thread_data *td; @@ -1359,6 +1361,13 @@ void show_run_stats(void) free(threadstats); } +void show_run_stats(void) +{ + fio_mutex_down(stat_mutex); + __show_run_stats(); + fio_mutex_up(stat_mutex); +} + static void *__show_running_run_stats(void fio_unused *arg) { struct thread_data *td; @@ -1393,7 +1402,7 @@ static void *__show_running_run_stats(void fio_unused *arg) td->update_rusage = 0; } - show_run_stats(); + __show_run_stats(); for_each_td(td, i) { if (td_read(td) && td->io_bytes[DDIR_READ]) @@ -1405,6 +1414,7 @@ static void *__show_running_run_stats(void fio_unused *arg) } free(rt); + fio_mutex_up(stat_mutex); return NULL; } @@ -1417,8 +1427,14 @@ void show_running_run_stats(void) { pthread_t thread; - pthread_create(&thread, NULL, __show_running_run_stats, NULL); - pthread_detach(thread); + fio_mutex_down(stat_mutex); + + if (!pthread_create(&thread, NULL, __show_running_run_stats, NULL)) { + pthread_detach(thread); + return; + } + + fio_mutex_up(stat_mutex); } static int status_interval_init; @@ -1701,3 +1717,18 @@ void add_iops_sample(struct thread_data *td, enum fio_ddir ddir, fio_gettime(&td->iops_sample_time, NULL); } + +void stat_init(void) +{ + stat_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED); +} + +void stat_exit(void) +{ + /* + * When we have the mutex, we know out-of-band access to it + * have ended. + */ + fio_mutex_down(stat_mutex); + fio_mutex_remove(stat_mutex); +} diff --git a/stat.h b/stat.h index b1bf5dc3..541b77e4 100644 --- a/stat.h +++ b/stat.h @@ -199,6 +199,9 @@ struct jobs_eta { uint8_t run_str[]; }; +extern void stat_init(void); +extern void stat_exit(void); + extern void show_thread_status(struct thread_stat *ts, struct group_run_stats *rs); extern void show_group_stats(struct group_run_stats *rs); extern int calc_thread_status(struct jobs_eta *je, int force);