diff options
author | Oleg Nesterov <oleg@redhat.com> | 2014-12-10 18:45:27 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 20:41:10 -0500 |
commit | 57a059187d5ba5592e36c6f23d046bc37616f346 (patch) | |
tree | 49c68a0167f2c148e1e275cb6b728825be152b02 /kernel/exit.c | |
parent | dc2fd4b00946751ebd222d366fc64550e4188dc2 (diff) |
exit: reparent: cleanup the changing of ->parent
1. Cosmetic, but "if (t->parent == father)" looks a bit confusing.
We need to change t->parent if and only if t is not traced.
2. If we actually want this BUG_ON() to ensure that parent/ptrace
match each other, then we should also take ptrace_reparented()
case into account too.
3. Change this code to use for_each_thread() instead of deprecated
while_each_thread().
[dan.carpenter@oracle.com: silence a bogus static checker warning]
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: Aaron Tomlin <atomlin@redhat.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>,
Cc: Sterling Alexander <stalexan@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Roland McGrath <roland@hack.frob.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 0272305bf855..464971e6923e 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -557,7 +557,7 @@ static void reparent_leader(struct task_struct *father, struct task_struct *p, | |||
557 | 557 | ||
558 | static void forget_original_parent(struct task_struct *father) | 558 | static void forget_original_parent(struct task_struct *father) |
559 | { | 559 | { |
560 | struct task_struct *p, *n, *reaper; | 560 | struct task_struct *p, *t, *n, *reaper; |
561 | LIST_HEAD(dead_children); | 561 | LIST_HEAD(dead_children); |
562 | 562 | ||
563 | write_lock_irq(&tasklist_lock); | 563 | write_lock_irq(&tasklist_lock); |
@@ -569,18 +569,15 @@ static void forget_original_parent(struct task_struct *father) | |||
569 | reaper = find_new_reaper(father); | 569 | reaper = find_new_reaper(father); |
570 | 570 | ||
571 | list_for_each_entry_safe(p, n, &father->children, sibling) { | 571 | list_for_each_entry_safe(p, n, &father->children, sibling) { |
572 | struct task_struct *t = p; | 572 | for_each_thread(p, t) { |
573 | |||
574 | do { | ||
575 | t->real_parent = reaper; | 573 | t->real_parent = reaper; |
576 | if (t->parent == father) { | 574 | BUG_ON((!t->ptrace) != (t->parent == father)); |
577 | BUG_ON(t->ptrace); | 575 | if (likely(!t->ptrace)) |
578 | t->parent = t->real_parent; | 576 | t->parent = t->real_parent; |
579 | } | ||
580 | if (t->pdeath_signal) | 577 | if (t->pdeath_signal) |
581 | group_send_sig_info(t->pdeath_signal, | 578 | group_send_sig_info(t->pdeath_signal, |
582 | SEND_SIG_NOINFO, t); | 579 | SEND_SIG_NOINFO, t); |
583 | } while_each_thread(p, t); | 580 | } |
584 | reparent_leader(father, p, &dead_children); | 581 | reparent_leader(father, p, &dead_children); |
585 | } | 582 | } |
586 | write_unlock_irq(&tasklist_lock); | 583 | write_unlock_irq(&tasklist_lock); |