From 49619dfd7771ee483ddf66091659f5a48d98d1ee Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Fri, 7 Jun 2013 05:58:52 +0000 Subject: [PATCH] scst: Fix scst_suspend_activity() timeout handling Make sure that suspend_count is decremented if scst_suspend_activity() times out. Also, if a timeout is encountered, clear SCST_FLAG_SUSPENDING before waking up the command threads instead of after waking up these threads. Reported-by: Sergey Tashkinov Signed-off-by: Bart Van Assche with some fixes and improvements git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4897 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_main.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index fa444eead..953682368 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -712,11 +712,9 @@ static int scst_susp_wait(unsigned long timeout) if (timeout != SCST_SUSPEND_TIMEOUT_UNLIMITED) { res = wait_event_interruptible_timeout(scst_dev_cmd_waitQ, (scst_get_cmd_counter() == 0), timeout); - if (res <= 0) { - __scst_resume_activity(); - if (res == 0) - res = -EBUSY; - } else + if (res == 0) + res = -EBUSY; + else if (res > 0) res = 0; } else wait_event(scst_dev_cmd_waitQ, scst_get_cmd_counter() == 0); @@ -816,7 +814,7 @@ int scst_suspend_activity(unsigned long timeout) /* just in case */ if (wait_time >= timeout) { res = -EBUSY; - goto out_clear; + goto out_resume; } wait_time = timeout - wait_time; } else @@ -824,7 +822,7 @@ int scst_suspend_activity(unsigned long timeout) res = scst_susp_wait(wait_time); if (res != 0) - goto out_clear; + goto out_resume; if (rep) PRINT_INFO("%s", "All active commands completed"); @@ -847,10 +845,14 @@ out_clear: clear_bit(SCST_FLAG_SUSPENDING, &scst_flags); /* See comment about smp_mb() above */ smp_mb__after_clear_bit(); + +out_resume: + __scst_resume_activity(); goto out_up; } EXPORT_SYMBOL_GPL(scst_suspend_activity); +/* scst_suspend_mutex supposed to be locked */ static void __scst_resume_activity(void) { struct scst_cmd_threads *l;