aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/exit.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 179ac74bf911..3f2182ccf187 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -666,10 +666,14 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
666 * the child reaper process (ie "init") in our pid 666 * the child reaper process (ie "init") in our pid
667 * space. 667 * space.
668 */ 668 */
669static void 669static void forget_original_parent(struct task_struct *father)
670forget_original_parent(struct task_struct *father, struct list_head *to_release)
671{ 670{
672 struct task_struct *p, *n, *reaper = father; 671 struct task_struct *p, *n, *reaper = father;
672 struct list_head ptrace_dead;
673
674 INIT_LIST_HEAD(&ptrace_dead);
675
676 write_lock_irq(&tasklist_lock);
673 677
674 do { 678 do {
675 reaper = next_thread(reaper); 679 reaper = next_thread(reaper);
@@ -677,7 +681,7 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
677 reaper = task_child_reaper(father); 681 reaper = task_child_reaper(father);
678 break; 682 break;
679 } 683 }
680 } while (reaper->exit_state); 684 } while (reaper->flags & PF_EXITING);
681 685
682 /* 686 /*
683 * There are only two places where our children can be: 687 * There are only two places where our children can be:
@@ -714,12 +718,23 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
714 * while it was being traced by us, to be able to see it in wait4. 718 * while it was being traced by us, to be able to see it in wait4.
715 */ 719 */
716 if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1)) 720 if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1))
717 list_add(&p->ptrace_list, to_release); 721 list_add(&p->ptrace_list, &ptrace_dead);
718 } 722 }
723
719 list_for_each_entry_safe(p, n, &father->ptrace_children, ptrace_list) { 724 list_for_each_entry_safe(p, n, &father->ptrace_children, ptrace_list) {
720 p->real_parent = reaper; 725 p->real_parent = reaper;
721 reparent_thread(p, father, 1); 726 reparent_thread(p, father, 1);
722 } 727 }
728
729 write_unlock_irq(&tasklist_lock);
730 BUG_ON(!list_empty(&father->children));
731 BUG_ON(!list_empty(&father->ptrace_children));
732
733 list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_list) {
734 list_del_init(&p->ptrace_list);
735 release_task(p);
736 }
737
723} 738}
724 739
725/* 740/*
@@ -730,7 +745,6 @@ static void exit_notify(struct task_struct *tsk)
730{ 745{
731 int state; 746 int state;
732 struct task_struct *t; 747 struct task_struct *t;
733 struct list_head ptrace_dead, *_p, *_n;
734 struct pid *pgrp; 748 struct pid *pgrp;
735 749
736 if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT) 750 if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
@@ -751,8 +765,6 @@ static void exit_notify(struct task_struct *tsk)
751 spin_unlock_irq(&tsk->sighand->siglock); 765 spin_unlock_irq(&tsk->sighand->siglock);
752 } 766 }
753 767
754 write_lock_irq(&tasklist_lock);
755
756 /* 768 /*
757 * This does two things: 769 * This does two things:
758 * 770 *
@@ -761,12 +773,9 @@ static void exit_notify(struct task_struct *tsk)
761 * as a result of our exiting, and if they have any stopped 773 * as a result of our exiting, and if they have any stopped
762 * jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2) 774 * jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
763 */ 775 */
776 forget_original_parent(tsk);
764 777
765 INIT_LIST_HEAD(&ptrace_dead); 778 write_lock_irq(&tasklist_lock);
766 forget_original_parent(tsk, &ptrace_dead);
767 BUG_ON(!list_empty(&tsk->children));
768 BUG_ON(!list_empty(&tsk->ptrace_children));
769
770 /* 779 /*
771 * Check to see if any process groups have become orphaned 780 * Check to see if any process groups have become orphaned
772 * as a result of our exiting, and if they have any stopped 781 * as a result of our exiting, and if they have any stopped
@@ -831,12 +840,6 @@ static void exit_notify(struct task_struct *tsk)
831 840
832 write_unlock_irq(&tasklist_lock); 841 write_unlock_irq(&tasklist_lock);
833 842
834 list_for_each_safe(_p, _n, &ptrace_dead) {
835 list_del_init(_p);
836 t = list_entry(_p, struct task_struct, ptrace_list);
837 release_task(t);
838 }
839
840 /* If the process is dead, release it - nobody will wait for it */ 843 /* If the process is dead, release it - nobody will wait for it */
841 if (state == EXIT_DEAD) 844 if (state == EXIT_DEAD)
842 release_task(tsk); 845 release_task(tsk);