Browse Source

DLM: fix race condition between dlm_recoverd_stop and dlm_recoverd

When dlm_recoverd_stop() is called between kthread_should_stop() and
set_task_state(TASK_INTERRUPTIBLE), dlm_recoverd will not wake up.

Signed-off-by: Tadashi Miyauchi <miyauchi@toshiba-tops.co.jp>
Signed-off-by: Tsutomu Owa <tsutomu.owa@toshiba.co.jp>
Signed-off-by: David Teigland <teigland@redhat.com>
tsutomu.owa@toshiba.co.jp 8 years ago
parent
commit
e412f9201d
1 changed files with 10 additions and 1 deletions
  1. 10 1
      fs/dlm/recoverd.c

+ 10 - 1
fs/dlm/recoverd.c

@@ -287,8 +287,17 @@ static int dlm_recoverd(void *arg)
 	set_bit(LSFL_RECOVER_LOCK, &ls->ls_flags);
 	set_bit(LSFL_RECOVER_LOCK, &ls->ls_flags);
 	wake_up(&ls->ls_recover_lock_wait);
 	wake_up(&ls->ls_recover_lock_wait);
 
 
-	while (!kthread_should_stop()) {
+	while (1) {
+		/*
+		 * We call kthread_should_stop() after set_current_state().
+		 * This is because it works correctly if kthread_stop() is
+		 * called just before set_current_state().
+		 */
 		set_current_state(TASK_INTERRUPTIBLE);
 		set_current_state(TASK_INTERRUPTIBLE);
+		if (kthread_should_stop()) {
+			set_current_state(TASK_RUNNING);
+			break;
+		}
 		if (!test_bit(LSFL_RECOVER_WORK, &ls->ls_flags) &&
 		if (!test_bit(LSFL_RECOVER_WORK, &ls->ls_flags) &&
 		    !test_bit(LSFL_RECOVER_DOWN, &ls->ls_flags))
 		    !test_bit(LSFL_RECOVER_DOWN, &ls->ls_flags))
 			schedule();
 			schedule();