From d483951ebe6e040e53579640a32eeb4e6fe189cf Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Wed, 4 Dec 2019 08:51:33 -0500 Subject: [PATCH] Free thread memory after it is stopped. After marking thread as ready to stop, CAS was waiting this for thread to exit out of main execution loop (in _cas_io_queue_thread()). In case of management queue it lead to deadlock because both stoping queue and main execution loop was performed in the same execution context. Since freeing memory is the only operation after stopping thread, it can be moved just after the main thread loop. After this little reordering, synchronising between _cas_stop_thread() and _cas_io_queue_thread() in no longer needed, and no deadlock will occur. This change is needed to put management qeueue from completion context. Without this cachnge, there will be no possiblitiy to stop cache from completion context and to make rollback. Signed-off-by: Michal Mielewczyk --- modules/cas_cache/threads.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/modules/cas_cache/threads.c b/modules/cas_cache/threads.c index d4d5f80..3ffcd42 100644 --- a/modules/cas_cache/threads.c +++ b/modules/cas_cache/threads.c @@ -50,9 +50,10 @@ static int _cas_io_queue_thread(void *data) WARN(ocf_queue_pending_io(q), "Still pending IO requests\n"); /* If we get here, then thread was signalled to terminate. - * So, let's complete and exit. + * So, let's free memory and exit. */ - complete_and_exit(&info->compl, 0); + printk(KERN_DEBUG "Thread %s stopped\n", info->name); + kfree(info); return 0; } @@ -201,13 +202,9 @@ static void _cas_start_thread(struct cas_thread_info *info) static void _cas_stop_thread(struct cas_thread_info *info) { if (info->running && info->thread) { - init_completion(&info->compl); atomic_set(&info->stop, 1); wake_up(&info->wq); - wait_for_completion(&info->compl); - printk(KERN_DEBUG "Thread %s stopped\n", info->name); } - kfree(info); } int cas_create_queue_thread(ocf_queue_t q, int cpu)