From e49da284e9cc7a5e7e4c7ab0eb64c6279627aa36 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Tue, 20 May 2014 23:39:57 +0000 Subject: [PATCH] Prevent potential deadlock between scst_del_threads() and commands taking scst_mutex git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5532 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_sysfs.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 5a79679bf..d9768fa5a 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -6060,10 +6060,20 @@ static int scst_process_threads_store(int newtn) TRACE_DBG("newtn %d", newtn); - res = mutex_lock_interruptible(&scst_mutex); + /* + * Some commands are taking scst_mutex on commands processing path, + * so we need to drain them, because otherwise we can fall into a + * deadlock with kthread_stop() in scst_del_threads() waiting for + * those commands to finish. + */ + res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER); if (res != 0) goto out; + res = mutex_lock_interruptible(&scst_mutex); + if (res != 0) + goto out_resume; + oldtn = scst_main_cmd_threads.nr_threads; delta = newtn - oldtn; @@ -6080,6 +6090,9 @@ static int scst_process_threads_store(int newtn) out_up: mutex_unlock(&scst_mutex); +out_resume: + scst_resume_activity(); + out: TRACE_EXIT_RES(res); return res;