diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 3b25b182d2be..537394b25e8d 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -547,7 +547,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) | |||
547 | 547 | ||
548 | if (p->pdeath_signal) | 548 | if (p->pdeath_signal) |
549 | /* We already hold the tasklist_lock here. */ | 549 | /* We already hold the tasklist_lock here. */ |
550 | group_send_sig_info(p->pdeath_signal, (void *) 0, p); | 550 | group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); |
551 | 551 | ||
552 | /* Move the child from its dying parent to the new one. */ | 552 | /* Move the child from its dying parent to the new one. */ |
553 | if (unlikely(traced)) { | 553 | if (unlikely(traced)) { |
@@ -591,8 +591,8 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) | |||
591 | int pgrp = process_group(p); | 591 | int pgrp = process_group(p); |
592 | 592 | ||
593 | if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { | 593 | if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { |
594 | __kill_pg_info(SIGHUP, (void *)1, pgrp); | 594 | __kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp); |
595 | __kill_pg_info(SIGCONT, (void *)1, pgrp); | 595 | __kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp); |
596 | } | 596 | } |
597 | } | 597 | } |
598 | } | 598 | } |
@@ -727,8 +727,8 @@ static void exit_notify(struct task_struct *tsk) | |||
727 | (t->signal->session == tsk->signal->session) && | 727 | (t->signal->session == tsk->signal->session) && |
728 | will_become_orphaned_pgrp(process_group(tsk), tsk) && | 728 | will_become_orphaned_pgrp(process_group(tsk), tsk) && |
729 | has_stopped_jobs(process_group(tsk))) { | 729 | has_stopped_jobs(process_group(tsk))) { |
730 | __kill_pg_info(SIGHUP, (void *)1, process_group(tsk)); | 730 | __kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk)); |
731 | __kill_pg_info(SIGCONT, (void *)1, process_group(tsk)); | 731 | __kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk)); |
732 | } | 732 | } |
733 | 733 | ||
734 | /* Let father know we died | 734 | /* Let father know we died |
@@ -783,10 +783,6 @@ static void exit_notify(struct task_struct *tsk) | |||
783 | /* If the process is dead, release it - nobody will wait for it */ | 783 | /* If the process is dead, release it - nobody will wait for it */ |
784 | if (state == EXIT_DEAD) | 784 | if (state == EXIT_DEAD) |
785 | release_task(tsk); | 785 | release_task(tsk); |
786 | |||
787 | /* PF_DEAD causes final put_task_struct after we schedule. */ | ||
788 | preempt_disable(); | ||
789 | tsk->flags |= PF_DEAD; | ||
790 | } | 786 | } |
791 | 787 | ||
792 | fastcall NORET_TYPE void do_exit(long code) | 788 | fastcall NORET_TYPE void do_exit(long code) |
@@ -839,7 +835,10 @@ fastcall NORET_TYPE void do_exit(long code) | |||
839 | preempt_count()); | 835 | preempt_count()); |
840 | 836 | ||
841 | acct_update_integrals(tsk); | 837 | acct_update_integrals(tsk); |
842 | update_mem_hiwater(tsk); | 838 | if (tsk->mm) { |
839 | update_hiwater_rss(tsk->mm); | ||
840 | update_hiwater_vm(tsk->mm); | ||
841 | } | ||
843 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 842 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
844 | if (group_dead) { | 843 | if (group_dead) { |
845 | del_timer_sync(&tsk->signal->real_timer); | 844 | del_timer_sync(&tsk->signal->real_timer); |
@@ -870,7 +869,11 @@ fastcall NORET_TYPE void do_exit(long code) | |||
870 | tsk->mempolicy = NULL; | 869 | tsk->mempolicy = NULL; |
871 | #endif | 870 | #endif |
872 | 871 | ||
873 | BUG_ON(!(current->flags & PF_DEAD)); | 872 | /* PF_DEAD causes final put_task_struct after we schedule. */ |
873 | preempt_disable(); | ||
874 | BUG_ON(tsk->flags & PF_DEAD); | ||
875 | tsk->flags |= PF_DEAD; | ||
876 | |||
874 | schedule(); | 877 | schedule(); |
875 | BUG(); | 878 | BUG(); |
876 | /* Avoid "noreturn function does return". */ | 879 | /* Avoid "noreturn function does return". */ |
@@ -1380,6 +1383,15 @@ repeat: | |||
1380 | 1383 | ||
1381 | switch (p->state) { | 1384 | switch (p->state) { |
1382 | case TASK_TRACED: | 1385 | case TASK_TRACED: |
1386 | /* | ||
1387 | * When we hit the race with PTRACE_ATTACH, | ||
1388 | * we will not report this child. But the | ||
1389 | * race means it has not yet been moved to | ||
1390 | * our ptrace_children list, so we need to | ||
1391 | * set the flag here to avoid a spurious ECHILD | ||
1392 | * when the race happens with the only child. | ||
1393 | */ | ||
1394 | flag = 1; | ||
1383 | if (!my_ptrace_child(p)) | 1395 | if (!my_ptrace_child(p)) |
1384 | continue; | 1396 | continue; |
1385 | /*FALLTHROUGH*/ | 1397 | /*FALLTHROUGH*/ |