diff options
| -rw-r--r-- | fs/exec.c | 28 | ||||
| -rw-r--r-- | kernel/exit.c | 10 |
2 files changed, 22 insertions, 16 deletions
| @@ -801,16 +801,15 @@ static int de_thread(struct task_struct *tsk) | |||
| 801 | hrtimer_restart(&sig->real_timer); | 801 | hrtimer_restart(&sig->real_timer); |
| 802 | spin_lock_irq(lock); | 802 | spin_lock_irq(lock); |
| 803 | } | 803 | } |
| 804 | |||
| 805 | sig->notify_count = count; | ||
| 806 | sig->group_exit_task = tsk; | ||
| 804 | while (atomic_read(&sig->count) > count) { | 807 | while (atomic_read(&sig->count) > count) { |
| 805 | sig->group_exit_task = tsk; | ||
| 806 | sig->notify_count = count; | ||
| 807 | __set_current_state(TASK_UNINTERRUPTIBLE); | 808 | __set_current_state(TASK_UNINTERRUPTIBLE); |
| 808 | spin_unlock_irq(lock); | 809 | spin_unlock_irq(lock); |
| 809 | schedule(); | 810 | schedule(); |
| 810 | spin_lock_irq(lock); | 811 | spin_lock_irq(lock); |
| 811 | } | 812 | } |
| 812 | sig->group_exit_task = NULL; | ||
| 813 | sig->notify_count = 0; | ||
| 814 | spin_unlock_irq(lock); | 813 | spin_unlock_irq(lock); |
| 815 | 814 | ||
| 816 | /* | 815 | /* |
| @@ -819,14 +818,17 @@ static int de_thread(struct task_struct *tsk) | |||
| 819 | * and to assume its PID: | 818 | * and to assume its PID: |
| 820 | */ | 819 | */ |
| 821 | if (!thread_group_leader(tsk)) { | 820 | if (!thread_group_leader(tsk)) { |
| 822 | /* | ||
| 823 | * Wait for the thread group leader to be a zombie. | ||
| 824 | * It should already be zombie at this point, most | ||
| 825 | * of the time. | ||
| 826 | */ | ||
| 827 | leader = tsk->group_leader; | 821 | leader = tsk->group_leader; |
| 828 | while (leader->exit_state != EXIT_ZOMBIE) | 822 | |
| 829 | yield(); | 823 | sig->notify_count = -1; |
| 824 | for (;;) { | ||
| 825 | write_lock_irq(&tasklist_lock); | ||
| 826 | if (likely(leader->exit_state)) | ||
| 827 | break; | ||
| 828 | __set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 829 | write_unlock_irq(&tasklist_lock); | ||
| 830 | schedule(); | ||
| 831 | } | ||
| 830 | 832 | ||
| 831 | /* | 833 | /* |
| 832 | * The only record we have of the real-time age of a | 834 | * The only record we have of the real-time age of a |
| @@ -840,8 +842,6 @@ static int de_thread(struct task_struct *tsk) | |||
| 840 | */ | 842 | */ |
| 841 | tsk->start_time = leader->start_time; | 843 | tsk->start_time = leader->start_time; |
| 842 | 844 | ||
| 843 | write_lock_irq(&tasklist_lock); | ||
| 844 | |||
| 845 | BUG_ON(leader->tgid != tsk->tgid); | 845 | BUG_ON(leader->tgid != tsk->tgid); |
| 846 | BUG_ON(tsk->pid == tsk->tgid); | 846 | BUG_ON(tsk->pid == tsk->tgid); |
| 847 | /* | 847 | /* |
| @@ -874,6 +874,8 @@ static int de_thread(struct task_struct *tsk) | |||
| 874 | write_unlock_irq(&tasklist_lock); | 874 | write_unlock_irq(&tasklist_lock); |
| 875 | } | 875 | } |
| 876 | 876 | ||
| 877 | sig->group_exit_task = NULL; | ||
| 878 | sig->notify_count = 0; | ||
| 877 | /* | 879 | /* |
| 878 | * There may be one thread left which is just exiting, | 880 | * There may be one thread left which is just exiting, |
| 879 | * but it's safe to stop telling the group to kill themselves. | 881 | * but it's safe to stop telling the group to kill themselves. |
diff --git a/kernel/exit.c b/kernel/exit.c index 25f6805be5fe..4c108df88a37 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -92,10 +92,9 @@ static void __exit_signal(struct task_struct *tsk) | |||
| 92 | * If there is any task waiting for the group exit | 92 | * If there is any task waiting for the group exit |
| 93 | * then notify it: | 93 | * then notify it: |
| 94 | */ | 94 | */ |
| 95 | if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) { | 95 | if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) |
| 96 | wake_up_process(sig->group_exit_task); | 96 | wake_up_process(sig->group_exit_task); |
| 97 | sig->group_exit_task = NULL; | 97 | |
| 98 | } | ||
| 99 | if (tsk == sig->curr_target) | 98 | if (tsk == sig->curr_target) |
| 100 | sig->curr_target = next_thread(tsk); | 99 | sig->curr_target = next_thread(tsk); |
| 101 | /* | 100 | /* |
| @@ -827,6 +826,11 @@ static void exit_notify(struct task_struct *tsk) | |||
| 827 | state = EXIT_DEAD; | 826 | state = EXIT_DEAD; |
| 828 | tsk->exit_state = state; | 827 | tsk->exit_state = state; |
| 829 | 828 | ||
| 829 | if (thread_group_leader(tsk) && | ||
| 830 | tsk->signal->notify_count < 0 && | ||
| 831 | tsk->signal->group_exit_task) | ||
| 832 | wake_up_process(tsk->signal->group_exit_task); | ||
| 833 | |||
| 830 | write_unlock_irq(&tasklist_lock); | 834 | write_unlock_irq(&tasklist_lock); |
| 831 | 835 | ||
| 832 | list_for_each_safe(_p, _n, &ptrace_dead) { | 836 | list_for_each_safe(_p, _n, &ptrace_dead) { |
