From a5b01f1ba8d45e9b16079d2759a96ad9cad08e16 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 11 Nov 2010 09:19:49 +0100 Subject: [PATCH 1/1] Call path below SIGALRM isn't safe We do allocations, open files, printf, etc from the SIGALRM signal handler which gets run every 250 msecs. This isn't necessarily safe and could deadlock. Move it to thread context instead. Signed-off-by: Jens Axboe --- eta.c | 6 +++++- fio.c | 41 ++++++++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/eta.c b/eta.c index 81dbfa7e..608e0dd4 100644 --- a/eta.c +++ b/eta.c @@ -328,7 +328,11 @@ void print_thread_status(void) } disp_time = mtime_since(&disp_prev_time, &now); - if (disp_time < 1000) + + /* + * Allow a little slack, the target is to print it every 1000 msecs + */ + if (disp_time < 900) return; calc_rate(disp_time, io_bytes, disp_io_bytes, rate); diff --git a/fio.c b/fio.c index d20fc245..91bf6b61 100644 --- a/fio.c +++ b/fio.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -62,7 +63,7 @@ static struct fio_mutex *startup_mutex; static struct fio_mutex *writeout_mutex; static volatile int fio_abort; static int exit_value; -static struct itimerval itimer; +static timer_t ival_timer; static pthread_t gtod_thread; static struct flist_head *cgroup_list; static char *cgroup_mnt; @@ -113,17 +114,21 @@ static void terminate_threads(int group_id) static void status_timer_arm(void) { - itimer.it_value.tv_sec = 0; - itimer.it_value.tv_usec = DISK_UTIL_MSEC * 1000; - setitimer(ITIMER_REAL, &itimer, NULL); + struct itimerspec value; + + value.it_value.tv_sec = 0; + value.it_value.tv_nsec = DISK_UTIL_MSEC * 1000000; + value.it_interval.tv_sec = 0; + value.it_interval.tv_nsec = DISK_UTIL_MSEC * 1000000; + + timer_settime(ival_timer, 0, &value, NULL); } -static void sig_alrm(int fio_unused sig) +static void ival_fn(union sigval sig) { if (threads) { update_io_ticks(); print_thread_status(); - status_timer_arm(); } } @@ -143,15 +148,27 @@ static void sig_int(int sig) } } +static void posix_timer_teardown(void) +{ + timer_delete(ival_timer); +} + +static void posix_timer_setup(void) +{ + struct sigevent evt; + + memset(&evt, 0, sizeof(evt)); + evt.sigev_notify = SIGEV_THREAD; + evt.sigev_notify_function = ival_fn; + + if (timer_create(CLOCK_MONOTONIC, &evt, &ival_timer) < 0) + perror("timer_create"); +} + static void set_sig_handlers(void) { struct sigaction act; - memset(&act, 0, sizeof(act)); - act.sa_handler = sig_alrm; - act.sa_flags = SA_RESTART; - sigaction(SIGALRM, &act, NULL); - memset(&act, 0, sizeof(act)); act.sa_handler = sig_int; act.sa_flags = SA_RESTART; @@ -1689,6 +1706,7 @@ int main(int argc, char *argv[]) set_genesis_time(); + posix_timer_setup(); status_timer_arm(); cgroup_list = smalloc(sizeof(*cgroup_list)); @@ -1709,6 +1727,7 @@ int main(int argc, char *argv[]) sfree(cgroup_list); sfree(cgroup_mnt); + posix_timer_teardown(); fio_mutex_remove(startup_mutex); fio_mutex_remove(writeout_mutex); return exit_value; -- 2.25.1