diff options
Diffstat (limited to 'kernel/exit.c')
| -rw-r--r-- | kernel/exit.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index abf9cf3b95c6..b6c90b5ef509 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -48,7 +48,8 @@ | |||
| 48 | #include <linux/tracehook.h> | 48 | #include <linux/tracehook.h> |
| 49 | #include <linux/fs_struct.h> | 49 | #include <linux/fs_struct.h> |
| 50 | #include <linux/init_task.h> | 50 | #include <linux/init_task.h> |
| 51 | #include <trace/sched.h> | 51 | #include <linux/perf_counter.h> |
| 52 | #include <trace/events/sched.h> | ||
| 52 | 53 | ||
| 53 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
| 54 | #include <asm/unistd.h> | 55 | #include <asm/unistd.h> |
| @@ -56,10 +57,6 @@ | |||
| 56 | #include <asm/mmu_context.h> | 57 | #include <asm/mmu_context.h> |
| 57 | #include "cred-internals.h" | 58 | #include "cred-internals.h" |
| 58 | 59 | ||
| 59 | DEFINE_TRACE(sched_process_free); | ||
| 60 | DEFINE_TRACE(sched_process_exit); | ||
| 61 | DEFINE_TRACE(sched_process_wait); | ||
| 62 | |||
| 63 | static void exit_mm(struct task_struct * tsk); | 60 | static void exit_mm(struct task_struct * tsk); |
| 64 | 61 | ||
| 65 | static void __unhash_process(struct task_struct *p) | 62 | static void __unhash_process(struct task_struct *p) |
| @@ -158,6 +155,9 @@ static void delayed_put_task_struct(struct rcu_head *rhp) | |||
| 158 | { | 155 | { |
| 159 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); | 156 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); |
| 160 | 157 | ||
| 158 | #ifdef CONFIG_PERF_COUNTERS | ||
| 159 | WARN_ON_ONCE(tsk->perf_counter_ctxp); | ||
| 160 | #endif | ||
| 161 | trace_sched_process_free(tsk); | 161 | trace_sched_process_free(tsk); |
| 162 | put_task_struct(tsk); | 162 | put_task_struct(tsk); |
| 163 | } | 163 | } |
| @@ -174,6 +174,7 @@ repeat: | |||
| 174 | atomic_dec(&__task_cred(p)->user->processes); | 174 | atomic_dec(&__task_cred(p)->user->processes); |
| 175 | 175 | ||
| 176 | proc_flush_task(p); | 176 | proc_flush_task(p); |
| 177 | |||
| 177 | write_lock_irq(&tasklist_lock); | 178 | write_lock_irq(&tasklist_lock); |
| 178 | tracehook_finish_release_task(p); | 179 | tracehook_finish_release_task(p); |
| 179 | __exit_signal(p); | 180 | __exit_signal(p); |
| @@ -975,16 +976,19 @@ NORET_TYPE void do_exit(long code) | |||
| 975 | module_put(tsk->binfmt->module); | 976 | module_put(tsk->binfmt->module); |
| 976 | 977 | ||
| 977 | proc_exit_connector(tsk); | 978 | proc_exit_connector(tsk); |
| 979 | |||
| 980 | /* | ||
| 981 | * Flush inherited counters to the parent - before the parent | ||
| 982 | * gets woken up by child-exit notifications. | ||
| 983 | */ | ||
| 984 | perf_counter_exit_task(tsk); | ||
| 985 | |||
| 978 | exit_notify(tsk, group_dead); | 986 | exit_notify(tsk, group_dead); |
| 979 | #ifdef CONFIG_NUMA | 987 | #ifdef CONFIG_NUMA |
| 980 | mpol_put(tsk->mempolicy); | 988 | mpol_put(tsk->mempolicy); |
| 981 | tsk->mempolicy = NULL; | 989 | tsk->mempolicy = NULL; |
| 982 | #endif | 990 | #endif |
| 983 | #ifdef CONFIG_FUTEX | 991 | #ifdef CONFIG_FUTEX |
| 984 | /* | ||
| 985 | * This must happen late, after the PID is not | ||
| 986 | * hashed anymore: | ||
| 987 | */ | ||
| 988 | if (unlikely(!list_empty(&tsk->pi_state_list))) | 992 | if (unlikely(!list_empty(&tsk->pi_state_list))) |
| 989 | exit_pi_state_list(tsk); | 993 | exit_pi_state_list(tsk); |
| 990 | if (unlikely(current->pi_state_cache)) | 994 | if (unlikely(current->pi_state_cache)) |
| @@ -1476,6 +1480,7 @@ static int wait_consider_task(struct task_struct *parent, int ptrace, | |||
| 1476 | */ | 1480 | */ |
| 1477 | if (*notask_error) | 1481 | if (*notask_error) |
| 1478 | *notask_error = ret; | 1482 | *notask_error = ret; |
| 1483 | return 0; | ||
| 1479 | } | 1484 | } |
| 1480 | 1485 | ||
| 1481 | if (likely(!ptrace) && unlikely(p->ptrace)) { | 1486 | if (likely(!ptrace) && unlikely(p->ptrace)) { |
