diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 2ef2ad540201..5b0fb9f09f21 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -72,6 +72,11 @@ repeat: | |||
72 | BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); | 72 | BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); |
73 | __exit_signal(p); | 73 | __exit_signal(p); |
74 | __exit_sighand(p); | 74 | __exit_sighand(p); |
75 | /* | ||
76 | * Note that the fastpath in sys_times depends on __exit_signal having | ||
77 | * updated the counters before a task is removed from the tasklist of | ||
78 | * the process by __unhash_process. | ||
79 | */ | ||
75 | __unhash_process(p); | 80 | __unhash_process(p); |
76 | 81 | ||
77 | /* | 82 | /* |
@@ -779,6 +784,8 @@ fastcall NORET_TYPE void do_exit(long code) | |||
779 | 784 | ||
780 | profile_task_exit(tsk); | 785 | profile_task_exit(tsk); |
781 | 786 | ||
787 | WARN_ON(atomic_read(&tsk->fs_excl)); | ||
788 | |||
782 | if (unlikely(in_interrupt())) | 789 | if (unlikely(in_interrupt())) |
783 | panic("Aiee, killing interrupt handler!"); | 790 | panic("Aiee, killing interrupt handler!"); |
784 | if (unlikely(!tsk->pid)) | 791 | if (unlikely(!tsk->pid)) |
@@ -793,6 +800,17 @@ fastcall NORET_TYPE void do_exit(long code) | |||
793 | ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP); | 800 | ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP); |
794 | } | 801 | } |
795 | 802 | ||
803 | /* | ||
804 | * We're taking recursive faults here in do_exit. Safest is to just | ||
805 | * leave this task alone and wait for reboot. | ||
806 | */ | ||
807 | if (unlikely(tsk->flags & PF_EXITING)) { | ||
808 | printk(KERN_ALERT | ||
809 | "Fixing recursive fault but reboot is needed!\n"); | ||
810 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
811 | schedule(); | ||
812 | } | ||
813 | |||
796 | tsk->flags |= PF_EXITING; | 814 | tsk->flags |= PF_EXITING; |
797 | 815 | ||
798 | /* | 816 | /* |
@@ -811,8 +829,10 @@ fastcall NORET_TYPE void do_exit(long code) | |||
811 | acct_update_integrals(tsk); | 829 | acct_update_integrals(tsk); |
812 | update_mem_hiwater(tsk); | 830 | update_mem_hiwater(tsk); |
813 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 831 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
814 | if (group_dead) | 832 | if (group_dead) { |
833 | del_timer_sync(&tsk->signal->real_timer); | ||
815 | acct_process(code); | 834 | acct_process(code); |
835 | } | ||
816 | exit_mm(tsk); | 836 | exit_mm(tsk); |
817 | 837 | ||
818 | exit_sem(tsk); | 838 | exit_sem(tsk); |