aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2008-07-25 04:47:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:39 -0400
commit15b9f360c0316c06d37c09b02d85565edbaf9dd3 (patch)
tree5e874b98b6f16ca1f376f5e4bd480da7ae5143b6 /fs
parent246bb0b1deb29726990620d8b5e55ca29f331362 (diff)
coredump: zap_threads() must skip kernel threads
The main loop in zap_threads() must skip kthreads which may use the same mm. Otherwise we "kill" this thread erroneously (for example, it can not fork or exec after that), and the coredumping task stucks in the TASK_UNINTERRUPTIBLE state forever because of the wrong ->core_waiters count. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/exec.c b/fs/exec.c
index cd2e8c9b1249..e347e6ed1617 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1574,11 +1574,12 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
1574 for_each_process(g) { 1574 for_each_process(g) {
1575 if (g == tsk->group_leader) 1575 if (g == tsk->group_leader)
1576 continue; 1576 continue;
1577 1577 if (g->flags & PF_KTHREAD)
1578 continue;
1578 p = g; 1579 p = g;
1579 do { 1580 do {
1580 if (p->mm) { 1581 if (p->mm) {
1581 if (p->mm == mm) { 1582 if (unlikely(p->mm == mm)) {
1582 lock_task_sighand(p, &flags); 1583 lock_task_sighand(p, &flags);
1583 zap_process(p); 1584 zap_process(p);
1584 unlock_task_sighand(p, &flags); 1585 unlock_task_sighand(p, &flags);