diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 94 |
1 files changed, 41 insertions, 53 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index f2b321bae440..2913b3509d42 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -85,7 +85,6 @@ static void __exit_signal(struct task_struct *tsk) | |||
85 | struct tty_struct *uninitialized_var(tty); | 85 | struct tty_struct *uninitialized_var(tty); |
86 | 86 | ||
87 | sighand = rcu_dereference_check(tsk->sighand, | 87 | sighand = rcu_dereference_check(tsk->sighand, |
88 | rcu_read_lock_held() || | ||
89 | lockdep_tasklist_lock_is_held()); | 88 | lockdep_tasklist_lock_is_held()); |
90 | spin_lock(&sighand->siglock); | 89 | spin_lock(&sighand->siglock); |
91 | 90 | ||
@@ -169,7 +168,6 @@ void release_task(struct task_struct * p) | |||
169 | struct task_struct *leader; | 168 | struct task_struct *leader; |
170 | int zap_leader; | 169 | int zap_leader; |
171 | repeat: | 170 | repeat: |
172 | tracehook_prepare_release_task(p); | ||
173 | /* don't need to get the RCU readlock here - the process is dead and | 171 | /* don't need to get the RCU readlock here - the process is dead and |
174 | * can't be modifying its own credentials. But shut RCU-lockdep up */ | 172 | * can't be modifying its own credentials. But shut RCU-lockdep up */ |
175 | rcu_read_lock(); | 173 | rcu_read_lock(); |
@@ -179,7 +177,7 @@ repeat: | |||
179 | proc_flush_task(p); | 177 | proc_flush_task(p); |
180 | 178 | ||
181 | write_lock_irq(&tasklist_lock); | 179 | write_lock_irq(&tasklist_lock); |
182 | tracehook_finish_release_task(p); | 180 | ptrace_release_task(p); |
183 | __exit_signal(p); | 181 | __exit_signal(p); |
184 | 182 | ||
185 | /* | 183 | /* |
@@ -190,22 +188,12 @@ repeat: | |||
190 | zap_leader = 0; | 188 | zap_leader = 0; |
191 | leader = p->group_leader; | 189 | leader = p->group_leader; |
192 | if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) { | 190 | if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) { |
193 | BUG_ON(task_detached(leader)); | ||
194 | do_notify_parent(leader, leader->exit_signal); | ||
195 | /* | 191 | /* |
196 | * If we were the last child thread and the leader has | 192 | * If we were the last child thread and the leader has |
197 | * exited already, and the leader's parent ignores SIGCHLD, | 193 | * exited already, and the leader's parent ignores SIGCHLD, |
198 | * then we are the one who should release the leader. | 194 | * then we are the one who should release the leader. |
199 | * | ||
200 | * do_notify_parent() will have marked it self-reaping in | ||
201 | * that case. | ||
202 | */ | ||
203 | zap_leader = task_detached(leader); | ||
204 | |||
205 | /* | ||
206 | * This maintains the invariant that release_task() | ||
207 | * only runs on a task in EXIT_DEAD, just for sanity. | ||
208 | */ | 195 | */ |
196 | zap_leader = do_notify_parent(leader, leader->exit_signal); | ||
209 | if (zap_leader) | 197 | if (zap_leader) |
210 | leader->exit_state = EXIT_DEAD; | 198 | leader->exit_state = EXIT_DEAD; |
211 | } | 199 | } |
@@ -277,18 +265,16 @@ int is_current_pgrp_orphaned(void) | |||
277 | return retval; | 265 | return retval; |
278 | } | 266 | } |
279 | 267 | ||
280 | static int has_stopped_jobs(struct pid *pgrp) | 268 | static bool has_stopped_jobs(struct pid *pgrp) |
281 | { | 269 | { |
282 | int retval = 0; | ||
283 | struct task_struct *p; | 270 | struct task_struct *p; |
284 | 271 | ||
285 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { | 272 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { |
286 | if (!task_is_stopped(p)) | 273 | if (p->signal->flags & SIGNAL_STOP_STOPPED) |
287 | continue; | 274 | return true; |
288 | retval = 1; | ||
289 | break; | ||
290 | } while_each_pid_task(pgrp, PIDTYPE_PGID, p); | 275 | } while_each_pid_task(pgrp, PIDTYPE_PGID, p); |
291 | return retval; | 276 | |
277 | return false; | ||
292 | } | 278 | } |
293 | 279 | ||
294 | /* | 280 | /* |
@@ -751,7 +737,7 @@ static void reparent_leader(struct task_struct *father, struct task_struct *p, | |||
751 | { | 737 | { |
752 | list_move_tail(&p->sibling, &p->real_parent->children); | 738 | list_move_tail(&p->sibling, &p->real_parent->children); |
753 | 739 | ||
754 | if (task_detached(p)) | 740 | if (p->exit_state == EXIT_DEAD) |
755 | return; | 741 | return; |
756 | /* | 742 | /* |
757 | * If this is a threaded reparent there is no need to | 743 | * If this is a threaded reparent there is no need to |
@@ -764,10 +750,9 @@ static void reparent_leader(struct task_struct *father, struct task_struct *p, | |||
764 | p->exit_signal = SIGCHLD; | 750 | p->exit_signal = SIGCHLD; |
765 | 751 | ||
766 | /* If it has exited notify the new parent about this child's death. */ | 752 | /* If it has exited notify the new parent about this child's death. */ |
767 | if (!task_ptrace(p) && | 753 | if (!p->ptrace && |
768 | p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) { | 754 | p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) { |
769 | do_notify_parent(p, p->exit_signal); | 755 | if (do_notify_parent(p, p->exit_signal)) { |
770 | if (task_detached(p)) { | ||
771 | p->exit_state = EXIT_DEAD; | 756 | p->exit_state = EXIT_DEAD; |
772 | list_move_tail(&p->sibling, dead); | 757 | list_move_tail(&p->sibling, dead); |
773 | } | 758 | } |
@@ -794,7 +779,7 @@ static void forget_original_parent(struct task_struct *father) | |||
794 | do { | 779 | do { |
795 | t->real_parent = reaper; | 780 | t->real_parent = reaper; |
796 | if (t->parent == father) { | 781 | if (t->parent == father) { |
797 | BUG_ON(task_ptrace(t)); | 782 | BUG_ON(t->ptrace); |
798 | t->parent = t->real_parent; | 783 | t->parent = t->real_parent; |
799 | } | 784 | } |
800 | if (t->pdeath_signal) | 785 | if (t->pdeath_signal) |
@@ -819,8 +804,7 @@ static void forget_original_parent(struct task_struct *father) | |||
819 | */ | 804 | */ |
820 | static void exit_notify(struct task_struct *tsk, int group_dead) | 805 | static void exit_notify(struct task_struct *tsk, int group_dead) |
821 | { | 806 | { |
822 | int signal; | 807 | bool autoreap; |
823 | void *cookie; | ||
824 | 808 | ||
825 | /* | 809 | /* |
826 | * This does two things: | 810 | * This does two things: |
@@ -851,26 +835,33 @@ static void exit_notify(struct task_struct *tsk, int group_dead) | |||
851 | * we have changed execution domain as these two values started | 835 | * we have changed execution domain as these two values started |
852 | * the same after a fork. | 836 | * the same after a fork. |
853 | */ | 837 | */ |
854 | if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) && | 838 | if (thread_group_leader(tsk) && tsk->exit_signal != SIGCHLD && |
855 | (tsk->parent_exec_id != tsk->real_parent->self_exec_id || | 839 | (tsk->parent_exec_id != tsk->real_parent->self_exec_id || |
856 | tsk->self_exec_id != tsk->parent_exec_id)) | 840 | tsk->self_exec_id != tsk->parent_exec_id)) |
857 | tsk->exit_signal = SIGCHLD; | 841 | tsk->exit_signal = SIGCHLD; |
858 | 842 | ||
859 | signal = tracehook_notify_death(tsk, &cookie, group_dead); | 843 | if (unlikely(tsk->ptrace)) { |
860 | if (signal >= 0) | 844 | int sig = thread_group_leader(tsk) && |
861 | signal = do_notify_parent(tsk, signal); | 845 | thread_group_empty(tsk) && |
846 | !ptrace_reparented(tsk) ? | ||
847 | tsk->exit_signal : SIGCHLD; | ||
848 | autoreap = do_notify_parent(tsk, sig); | ||
849 | } else if (thread_group_leader(tsk)) { | ||
850 | autoreap = thread_group_empty(tsk) && | ||
851 | do_notify_parent(tsk, tsk->exit_signal); | ||
852 | } else { | ||
853 | autoreap = true; | ||
854 | } | ||
862 | 855 | ||
863 | tsk->exit_state = signal == DEATH_REAP ? EXIT_DEAD : EXIT_ZOMBIE; | 856 | tsk->exit_state = autoreap ? EXIT_DEAD : EXIT_ZOMBIE; |
864 | 857 | ||
865 | /* mt-exec, de_thread() is waiting for group leader */ | 858 | /* mt-exec, de_thread() is waiting for group leader */ |
866 | if (unlikely(tsk->signal->notify_count < 0)) | 859 | if (unlikely(tsk->signal->notify_count < 0)) |
867 | wake_up_process(tsk->signal->group_exit_task); | 860 | wake_up_process(tsk->signal->group_exit_task); |
868 | write_unlock_irq(&tasklist_lock); | 861 | write_unlock_irq(&tasklist_lock); |
869 | 862 | ||
870 | tracehook_report_death(tsk, signal, cookie, group_dead); | ||
871 | |||
872 | /* If the process is dead, release it - nobody will wait for it */ | 863 | /* If the process is dead, release it - nobody will wait for it */ |
873 | if (signal == DEATH_REAP) | 864 | if (autoreap) |
874 | release_task(tsk); | 865 | release_task(tsk); |
875 | } | 866 | } |
876 | 867 | ||
@@ -906,7 +897,6 @@ NORET_TYPE void do_exit(long code) | |||
906 | 897 | ||
907 | profile_task_exit(tsk); | 898 | profile_task_exit(tsk); |
908 | 899 | ||
909 | WARN_ON(atomic_read(&tsk->fs_excl)); | ||
910 | WARN_ON(blk_needs_flush_plug(tsk)); | 900 | WARN_ON(blk_needs_flush_plug(tsk)); |
911 | 901 | ||
912 | if (unlikely(in_interrupt())) | 902 | if (unlikely(in_interrupt())) |
@@ -923,7 +913,7 @@ NORET_TYPE void do_exit(long code) | |||
923 | */ | 913 | */ |
924 | set_fs(USER_DS); | 914 | set_fs(USER_DS); |
925 | 915 | ||
926 | tracehook_report_exit(&code); | 916 | ptrace_event(PTRACE_EVENT_EXIT, code); |
927 | 917 | ||
928 | validate_creds_for_do_exit(tsk); | 918 | validate_creds_for_do_exit(tsk); |
929 | 919 | ||
@@ -990,6 +980,7 @@ NORET_TYPE void do_exit(long code) | |||
990 | trace_sched_process_exit(tsk); | 980 | trace_sched_process_exit(tsk); |
991 | 981 | ||
992 | exit_sem(tsk); | 982 | exit_sem(tsk); |
983 | exit_shm(tsk); | ||
993 | exit_files(tsk); | 984 | exit_files(tsk); |
994 | exit_fs(tsk); | 985 | exit_fs(tsk); |
995 | check_stack_usage(); | 986 | check_stack_usage(); |
@@ -1235,9 +1226,9 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1235 | traced = ptrace_reparented(p); | 1226 | traced = ptrace_reparented(p); |
1236 | /* | 1227 | /* |
1237 | * It can be ptraced but not reparented, check | 1228 | * It can be ptraced but not reparented, check |
1238 | * !task_detached() to filter out sub-threads. | 1229 | * thread_group_leader() to filter out sub-threads. |
1239 | */ | 1230 | */ |
1240 | if (likely(!traced) && likely(!task_detached(p))) { | 1231 | if (likely(!traced) && thread_group_leader(p)) { |
1241 | struct signal_struct *psig; | 1232 | struct signal_struct *psig; |
1242 | struct signal_struct *sig; | 1233 | struct signal_struct *sig; |
1243 | unsigned long maxrss; | 1234 | unsigned long maxrss; |
@@ -1345,16 +1336,13 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1345 | /* We dropped tasklist, ptracer could die and untrace */ | 1336 | /* We dropped tasklist, ptracer could die and untrace */ |
1346 | ptrace_unlink(p); | 1337 | ptrace_unlink(p); |
1347 | /* | 1338 | /* |
1348 | * If this is not a detached task, notify the parent. | 1339 | * If this is not a sub-thread, notify the parent. |
1349 | * If it's still not detached after that, don't release | 1340 | * If parent wants a zombie, don't release it now. |
1350 | * it now. | ||
1351 | */ | 1341 | */ |
1352 | if (!task_detached(p)) { | 1342 | if (thread_group_leader(p) && |
1353 | do_notify_parent(p, p->exit_signal); | 1343 | !do_notify_parent(p, p->exit_signal)) { |
1354 | if (!task_detached(p)) { | 1344 | p->exit_state = EXIT_ZOMBIE; |
1355 | p->exit_state = EXIT_ZOMBIE; | 1345 | p = NULL; |
1356 | p = NULL; | ||
1357 | } | ||
1358 | } | 1346 | } |
1359 | write_unlock_irq(&tasklist_lock); | 1347 | write_unlock_irq(&tasklist_lock); |
1360 | } | 1348 | } |
@@ -1367,7 +1355,8 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1367 | static int *task_stopped_code(struct task_struct *p, bool ptrace) | 1355 | static int *task_stopped_code(struct task_struct *p, bool ptrace) |
1368 | { | 1356 | { |
1369 | if (ptrace) { | 1357 | if (ptrace) { |
1370 | if (task_is_stopped_or_traced(p)) | 1358 | if (task_is_stopped_or_traced(p) && |
1359 | !(p->jobctl & JOBCTL_LISTENING)) | ||
1371 | return &p->exit_code; | 1360 | return &p->exit_code; |
1372 | } else { | 1361 | } else { |
1373 | if (p->signal->flags & SIGNAL_STOP_STOPPED) | 1362 | if (p->signal->flags & SIGNAL_STOP_STOPPED) |
@@ -1563,7 +1552,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, | |||
1563 | * Notification and reaping will be cascaded to the real | 1552 | * Notification and reaping will be cascaded to the real |
1564 | * parent when the ptracer detaches. | 1553 | * parent when the ptracer detaches. |
1565 | */ | 1554 | */ |
1566 | if (likely(!ptrace) && unlikely(task_ptrace(p))) { | 1555 | if (likely(!ptrace) && unlikely(p->ptrace)) { |
1567 | /* it will become visible, clear notask_error */ | 1556 | /* it will become visible, clear notask_error */ |
1568 | wo->notask_error = 0; | 1557 | wo->notask_error = 0; |
1569 | return 0; | 1558 | return 0; |
@@ -1606,8 +1595,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, | |||
1606 | * own children, it should create a separate process which | 1595 | * own children, it should create a separate process which |
1607 | * takes the role of real parent. | 1596 | * takes the role of real parent. |
1608 | */ | 1597 | */ |
1609 | if (likely(!ptrace) && task_ptrace(p) && | 1598 | if (likely(!ptrace) && p->ptrace && !ptrace_reparented(p)) |
1610 | same_thread_group(p->parent, p->real_parent)) | ||
1611 | return 0; | 1599 | return 0; |
1612 | 1600 | ||
1613 | /* | 1601 | /* |