summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMandeep Singh Baines <msb@chromium.org>2012-01-03 14:41:13 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-06 14:17:33 -0800
commit12ed227da1fb7099978c73b65a756caf51a95553 (patch)
tree0e4b81672bdb42063778e56de0541b1a995cd8c8
parente5697e5158f562e3e7130e2880a5d0abea6cd4cd (diff)
downloadlinux-stable-12ed227da1fb7099978c73b65a756caf51a95553.tar.gz
linux-stable-12ed227da1fb7099978c73b65a756caf51a95553.tar.bz2
linux-stable-12ed227da1fb7099978c73b65a756caf51a95553.zip
hung_task: fix false positive during vfork
commit f9fab10bbd768b0e5254e53a4a8477a94bfc4b96 upstream. vfork parent uninterruptibly and unkillably waits for its child to exec/exit. This wait is of unbounded length. Ignore such waits in the hung_task detector. Signed-off-by: Mandeep Singh Baines <msb@chromium.org> Reported-by: Sasha Levin <levinsasha928@gmail.com> LKML-Reference: <1325344394.28904.43.camel@lappy> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: John Kacur <jkacur@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--kernel/hung_task.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/kernel/hung_task.c b/kernel/hung_task.c
index ea640120ab86..e972276f12ff 100644
--- a/kernel/hung_task.c
+++ b/kernel/hung_task.c
@@ -74,11 +74,17 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
/*
* Ensure the task is not frozen.
- * Also, when a freshly created task is scheduled once, changes
- * its state to TASK_UNINTERRUPTIBLE without having ever been
- * switched out once, it musn't be checked.
+ * Also, skip vfork and any other user process that freezer should skip.
*/
- if (unlikely(t->flags & PF_FROZEN || !switch_count))
+ if (unlikely(t->flags & (PF_FROZEN | PF_FREEZER_SKIP)))
+ return;
+
+ /*
+ * When a freshly created task is scheduled once, changes its state to
+ * TASK_UNINTERRUPTIBLE without having ever been switched out once, it
+ * musn't be checked.
+ */
+ if (unlikely(!switch_count))
return;
if (switch_count != t->last_switch_count) {