diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index ee515683b92d..f8e609ff1893 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/smp_lock.h> | 11 | #include <linux/smp_lock.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/capability.h> | ||
13 | #include <linux/completion.h> | 14 | #include <linux/completion.h> |
14 | #include <linux/personality.h> | 15 | #include <linux/personality.h> |
15 | #include <linux/tty.h> | 16 | #include <linux/tty.h> |
@@ -29,6 +30,7 @@ | |||
29 | #include <linux/syscalls.h> | 30 | #include <linux/syscalls.h> |
30 | #include <linux/signal.h> | 31 | #include <linux/signal.h> |
31 | #include <linux/cn_proc.h> | 32 | #include <linux/cn_proc.h> |
33 | #include <linux/mutex.h> | ||
32 | 34 | ||
33 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
34 | #include <asm/unistd.h> | 36 | #include <asm/unistd.h> |
@@ -72,7 +74,6 @@ repeat: | |||
72 | __ptrace_unlink(p); | 74 | __ptrace_unlink(p); |
73 | BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); | 75 | BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); |
74 | __exit_signal(p); | 76 | __exit_signal(p); |
75 | __exit_sighand(p); | ||
76 | /* | 77 | /* |
77 | * Note that the fastpath in sys_times depends on __exit_signal having | 78 | * Note that the fastpath in sys_times depends on __exit_signal having |
78 | * updated the counters before a task is removed from the tasklist of | 79 | * updated the counters before a task is removed from the tasklist of |
@@ -258,7 +259,7 @@ static inline void reparent_to_init(void) | |||
258 | 259 | ||
259 | void __set_special_pids(pid_t session, pid_t pgrp) | 260 | void __set_special_pids(pid_t session, pid_t pgrp) |
260 | { | 261 | { |
261 | struct task_struct *curr = current; | 262 | struct task_struct *curr = current->group_leader; |
262 | 263 | ||
263 | if (curr->signal->session != session) { | 264 | if (curr->signal->session != session) { |
264 | detach_pid(curr, PIDTYPE_SID); | 265 | detach_pid(curr, PIDTYPE_SID); |
@@ -842,7 +843,7 @@ fastcall NORET_TYPE void do_exit(long code) | |||
842 | } | 843 | } |
843 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 844 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
844 | if (group_dead) { | 845 | if (group_dead) { |
845 | del_timer_sync(&tsk->signal->real_timer); | 846 | hrtimer_cancel(&tsk->signal->real_timer); |
846 | exit_itimers(tsk->signal); | 847 | exit_itimers(tsk->signal); |
847 | acct_process(code); | 848 | acct_process(code); |
848 | } | 849 | } |
@@ -870,6 +871,10 @@ fastcall NORET_TYPE void do_exit(long code) | |||
870 | mpol_free(tsk->mempolicy); | 871 | mpol_free(tsk->mempolicy); |
871 | tsk->mempolicy = NULL; | 872 | tsk->mempolicy = NULL; |
872 | #endif | 873 | #endif |
874 | /* | ||
875 | * If DEBUG_MUTEXES is on, make sure we are holding no locks: | ||
876 | */ | ||
877 | mutex_debug_check_no_locks_held(tsk); | ||
873 | 878 | ||
874 | /* PF_DEAD causes final put_task_struct after we schedule. */ | 879 | /* PF_DEAD causes final put_task_struct after we schedule. */ |
875 | preempt_disable(); | 880 | preempt_disable(); |
@@ -926,7 +931,6 @@ do_group_exit(int exit_code) | |||
926 | /* Another thread got here before we took the lock. */ | 931 | /* Another thread got here before we took the lock. */ |
927 | exit_code = sig->group_exit_code; | 932 | exit_code = sig->group_exit_code; |
928 | else { | 933 | else { |
929 | sig->flags = SIGNAL_GROUP_EXIT; | ||
930 | sig->group_exit_code = exit_code; | 934 | sig->group_exit_code = exit_code; |
931 | zap_other_threads(current); | 935 | zap_other_threads(current); |
932 | } | 936 | } |
@@ -1068,6 +1072,9 @@ static int wait_task_zombie(task_t *p, int noreap, | |||
1068 | } | 1072 | } |
1069 | 1073 | ||
1070 | if (likely(p->real_parent == p->parent) && likely(p->signal)) { | 1074 | if (likely(p->real_parent == p->parent) && likely(p->signal)) { |
1075 | struct signal_struct *psig; | ||
1076 | struct signal_struct *sig; | ||
1077 | |||
1071 | /* | 1078 | /* |
1072 | * The resource counters for the group leader are in its | 1079 | * The resource counters for the group leader are in its |
1073 | * own task_struct. Those for dead threads in the group | 1080 | * own task_struct. Those for dead threads in the group |
@@ -1084,24 +1091,26 @@ static int wait_task_zombie(task_t *p, int noreap, | |||
1084 | * here reaping other children at the same time. | 1091 | * here reaping other children at the same time. |
1085 | */ | 1092 | */ |
1086 | spin_lock_irq(&p->parent->sighand->siglock); | 1093 | spin_lock_irq(&p->parent->sighand->siglock); |
1087 | p->parent->signal->cutime = | 1094 | psig = p->parent->signal; |
1088 | cputime_add(p->parent->signal->cutime, | 1095 | sig = p->signal; |
1096 | psig->cutime = | ||
1097 | cputime_add(psig->cutime, | ||
1089 | cputime_add(p->utime, | 1098 | cputime_add(p->utime, |
1090 | cputime_add(p->signal->utime, | 1099 | cputime_add(sig->utime, |
1091 | p->signal->cutime))); | 1100 | sig->cutime))); |
1092 | p->parent->signal->cstime = | 1101 | psig->cstime = |
1093 | cputime_add(p->parent->signal->cstime, | 1102 | cputime_add(psig->cstime, |
1094 | cputime_add(p->stime, | 1103 | cputime_add(p->stime, |
1095 | cputime_add(p->signal->stime, | 1104 | cputime_add(sig->stime, |
1096 | p->signal->cstime))); | 1105 | sig->cstime))); |
1097 | p->parent->signal->cmin_flt += | 1106 | psig->cmin_flt += |
1098 | p->min_flt + p->signal->min_flt + p->signal->cmin_flt; | 1107 | p->min_flt + sig->min_flt + sig->cmin_flt; |
1099 | p->parent->signal->cmaj_flt += | 1108 | psig->cmaj_flt += |
1100 | p->maj_flt + p->signal->maj_flt + p->signal->cmaj_flt; | 1109 | p->maj_flt + sig->maj_flt + sig->cmaj_flt; |
1101 | p->parent->signal->cnvcsw += | 1110 | psig->cnvcsw += |
1102 | p->nvcsw + p->signal->nvcsw + p->signal->cnvcsw; | 1111 | p->nvcsw + sig->nvcsw + sig->cnvcsw; |
1103 | p->parent->signal->cnivcsw += | 1112 | psig->cnivcsw += |
1104 | p->nivcsw + p->signal->nivcsw + p->signal->cnivcsw; | 1113 | p->nivcsw + sig->nivcsw + sig->cnivcsw; |
1105 | spin_unlock_irq(&p->parent->sighand->siglock); | 1114 | spin_unlock_irq(&p->parent->sighand->siglock); |
1106 | } | 1115 | } |
1107 | 1116 | ||