From: Jerome Marchand <jmarchan@redhat.com> Date: Fri, 18 Jun 2010 15:15:51 -0400 Subject: [misc] handle dead hung uninterruptible tasks correctly Message-id: <4C1B8DA7.1020805@redhat.com> Patchwork-id: 26315 O-Subject: [RHEL5.6 PATCH] handle correctly dead tasks in check_hung_uninterruptible_tasks() Bugzilla: 582237 RH-Acked-by: Don Zickus <dzickus@redhat.com> RH-Acked-by: Amerigo Wang <amwang@redhat.com> RH-Acked-by: Oleg Nesterov <oleg@redhat.com> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=582237 Description: A few lines of code have been lost in the backport of the hung task detection feature (from check_hung_uninterruptible_tasks()): do_each_thread(g, t) { if (!max_count--) goto unlock; if (!--batch_count) { batch_count = HUNG_TASK_BATCHING; rcu_lock_break(g, t); >>> /* Exit if t or g was unhashed during refresh. */ >>> if (t->state == TASK_DEAD || g->state == TASK_DEAD) >>> goto unlock; } /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) check_hung_task(t, timeout); } while_each_thread(g, t); Without that bit of code we could end up working with non consistent data. Test status: Built and booted. I was not able to trigger a bug with the unpatched kernel, so I can't say I've tested the bugfix. Regards, Jerome diff --git a/kernel/hung_task.c b/kernel/hung_task.c index 0fc6038..59dcfe9 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -148,6 +148,10 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) if (!--batch_count) { batch_count = HUNG_TASK_BATCHING; rcu_lock_break(g, t); + /* Exit if t or g was unhashed during refresh. */ + if (t->flags & PF_DEAD || g->flags & PF_DEAD) + goto unlock; + } /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE)