From: Jens Axboe Date: Fri, 4 Dec 2015 20:15:36 +0000 (-0700) Subject: workqueue: fix potential ABBA deadlock in stats summing X-Git-Tag: fio-2.2.13~47 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=a6a3469ea8753a999b9bb9bea33299700d3094eb workqueue: fix potential ABBA deadlock in stats summing Signed-off-by: Jens Axboe --- diff --git a/workqueue.c b/workqueue.c index 27d1060c..7cd83bfd 100644 --- a/workqueue.c +++ b/workqueue.c @@ -217,13 +217,32 @@ static void sum_val(uint64_t *dst, uint64_t *src) } #endif -static void sum_ddir(struct thread_data *dst, struct thread_data *src, - enum fio_ddir ddir) +static void pthread_double_unlock(pthread_mutex_t *lock1, + pthread_mutex_t *lock2) { #ifndef CONFIG_SFAA - pthread_mutex_lock(&dst->io_wq.stat_lock); - pthread_mutex_lock(&src->io_wq.stat_lock); + pthread_mutex_unlock(lock1); + pthread_mutex_unlock(lock2); #endif +} + +static void pthread_double_lock(pthread_mutex_t *lock1, pthread_mutex_t *lock2) +{ +#ifndef CONFIG_SFAA + if (lock1 < lock2) { + pthread_mutex_lock(lock1); + pthread_mutex_lock(lock2); + } else { + pthread_mutex_lock(lock2); + pthread_mutex_lock(lock1); + } +#endif +} + +static void sum_ddir(struct thread_data *dst, struct thread_data *src, + enum fio_ddir ddir) +{ + pthread_double_lock(&dst->io_wq.stat_lock, &src->io_wq.stat_lock); sum_val(&dst->io_bytes[ddir], &src->io_bytes[ddir]); sum_val(&dst->io_blocks[ddir], &src->io_blocks[ddir]); @@ -231,10 +250,7 @@ static void sum_ddir(struct thread_data *dst, struct thread_data *src, sum_val(&dst->this_io_bytes[ddir], &src->this_io_bytes[ddir]); sum_val(&dst->bytes_done[ddir], &src->bytes_done[ddir]); -#ifndef CONFIG_SFAA - pthread_mutex_unlock(&src->io_wq.stat_lock); - pthread_mutex_unlock(&dst->io_wq.stat_lock); -#endif + pthread_double_unlock(&dst->io_wq.stat_lock, &src->io_wq.stat_lock); } static void update_accounting(struct submit_worker *sw)