diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 3fb7be001964..2639a30a8aa5 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -558,12 +558,14 @@ static struct task_struct *find_alive_thread(struct task_struct *p) | |||
558 | return NULL; | 558 | return NULL; |
559 | } | 559 | } |
560 | 560 | ||
561 | static struct task_struct *find_child_reaper(struct task_struct *father) | 561 | static struct task_struct *find_child_reaper(struct task_struct *father, |
562 | struct list_head *dead) | ||
562 | __releases(&tasklist_lock) | 563 | __releases(&tasklist_lock) |
563 | __acquires(&tasklist_lock) | 564 | __acquires(&tasklist_lock) |
564 | { | 565 | { |
565 | struct pid_namespace *pid_ns = task_active_pid_ns(father); | 566 | struct pid_namespace *pid_ns = task_active_pid_ns(father); |
566 | struct task_struct *reaper = pid_ns->child_reaper; | 567 | struct task_struct *reaper = pid_ns->child_reaper; |
568 | struct task_struct *p, *n; | ||
567 | 569 | ||
568 | if (likely(reaper != father)) | 570 | if (likely(reaper != father)) |
569 | return reaper; | 571 | return reaper; |
@@ -579,6 +581,12 @@ static struct task_struct *find_child_reaper(struct task_struct *father) | |||
579 | panic("Attempted to kill init! exitcode=0x%08x\n", | 581 | panic("Attempted to kill init! exitcode=0x%08x\n", |
580 | father->signal->group_exit_code ?: father->exit_code); | 582 | father->signal->group_exit_code ?: father->exit_code); |
581 | } | 583 | } |
584 | |||
585 | list_for_each_entry_safe(p, n, dead, ptrace_entry) { | ||
586 | list_del_init(&p->ptrace_entry); | ||
587 | release_task(p); | ||
588 | } | ||
589 | |||
582 | zap_pid_ns_processes(pid_ns); | 590 | zap_pid_ns_processes(pid_ns); |
583 | write_lock_irq(&tasklist_lock); | 591 | write_lock_irq(&tasklist_lock); |
584 | 592 | ||
@@ -668,7 +676,7 @@ static void forget_original_parent(struct task_struct *father, | |||
668 | exit_ptrace(father, dead); | 676 | exit_ptrace(father, dead); |
669 | 677 | ||
670 | /* Can drop and reacquire tasklist_lock */ | 678 | /* Can drop and reacquire tasklist_lock */ |
671 | reaper = find_child_reaper(father); | 679 | reaper = find_child_reaper(father, dead); |
672 | if (list_empty(&father->children)) | 680 | if (list_empty(&father->children)) |
673 | return; | 681 | return; |
674 | 682 | ||