diff options
-rw-r--r-- | include/linux/init_task.h | 9 | ||||
-rw-r--r-- | kernel/exit.c | 21 |
2 files changed, 18 insertions, 12 deletions
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 23fd8909b9e5..54fa2fa2c8e4 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -113,6 +113,14 @@ extern struct group_info init_groups; | |||
113 | # define CAP_INIT_BSET CAP_INIT_EFF_SET | 113 | # define CAP_INIT_BSET CAP_INIT_EFF_SET |
114 | #endif | 114 | #endif |
115 | 115 | ||
116 | #ifdef CONFIG_PERF_COUNTERS | ||
117 | # define INIT_PERF_COUNTERS(tsk) \ | ||
118 | .perf_counter_ctx.counter_list = \ | ||
119 | LIST_HEAD_INIT(tsk.perf_counter_ctx.counter_list), | ||
120 | #else | ||
121 | # define INIT_PERF_COUNTERS(tsk) | ||
122 | #endif | ||
123 | |||
116 | /* | 124 | /* |
117 | * INIT_TASK is used to set up the first task table, touch at | 125 | * INIT_TASK is used to set up the first task table, touch at |
118 | * your own risk!. Base=0, limit=0x1fffff (=2MB) | 126 | * your own risk!. Base=0, limit=0x1fffff (=2MB) |
@@ -180,6 +188,7 @@ extern struct group_info init_groups; | |||
180 | INIT_IDS \ | 188 | INIT_IDS \ |
181 | INIT_TRACE_IRQFLAGS \ | 189 | INIT_TRACE_IRQFLAGS \ |
182 | INIT_LOCKDEP \ | 190 | INIT_LOCKDEP \ |
191 | INIT_PERF_COUNTERS(tsk) \ | ||
183 | } | 192 | } |
184 | 193 | ||
185 | 194 | ||
diff --git a/kernel/exit.c b/kernel/exit.c index 244edfd96865..101b7eeff44c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -153,6 +153,9 @@ static void delayed_put_task_struct(struct rcu_head *rhp) | |||
153 | { | 153 | { |
154 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); | 154 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); |
155 | 155 | ||
156 | #ifdef CONFIG_PERF_COUNTERS | ||
157 | WARN_ON_ONCE(!list_empty(&tsk->perf_counter_ctx.counter_list)); | ||
158 | #endif | ||
156 | trace_sched_process_free(tsk); | 159 | trace_sched_process_free(tsk); |
157 | put_task_struct(tsk); | 160 | put_task_struct(tsk); |
158 | } | 161 | } |
@@ -922,12 +925,6 @@ static void exit_notify(struct task_struct *tsk, int group_dead) | |||
922 | forget_original_parent(tsk); | 925 | forget_original_parent(tsk); |
923 | exit_task_namespaces(tsk); | 926 | exit_task_namespaces(tsk); |
924 | 927 | ||
925 | /* | ||
926 | * Flush inherited counters to the parent - before the parent | ||
927 | * gets woken up by child-exit notifications. | ||
928 | */ | ||
929 | perf_counter_exit_task(tsk); | ||
930 | |||
931 | write_lock_irq(&tasklist_lock); | 928 | write_lock_irq(&tasklist_lock); |
932 | if (group_dead) | 929 | if (group_dead) |
933 | kill_orphaned_pgrp(tsk->group_leader, NULL); | 930 | kill_orphaned_pgrp(tsk->group_leader, NULL); |
@@ -1122,12 +1119,6 @@ NORET_TYPE void do_exit(long code) | |||
1122 | if (tsk->splice_pipe) | 1119 | if (tsk->splice_pipe) |
1123 | __free_pipe_info(tsk->splice_pipe); | 1120 | __free_pipe_info(tsk->splice_pipe); |
1124 | 1121 | ||
1125 | /* | ||
1126 | * These must happen late, after the PID is not | ||
1127 | * hashed anymore, but still at a point that may sleep: | ||
1128 | */ | ||
1129 | perf_counter_exit_task(tsk); | ||
1130 | |||
1131 | preempt_disable(); | 1122 | preempt_disable(); |
1132 | /* causes final put_task_struct in finish_task_switch(). */ | 1123 | /* causes final put_task_struct in finish_task_switch(). */ |
1133 | tsk->state = TASK_DEAD; | 1124 | tsk->state = TASK_DEAD; |
@@ -1371,6 +1362,12 @@ static int wait_task_zombie(struct task_struct *p, int options, | |||
1371 | */ | 1362 | */ |
1372 | read_unlock(&tasklist_lock); | 1363 | read_unlock(&tasklist_lock); |
1373 | 1364 | ||
1365 | /* | ||
1366 | * Flush inherited counters to the parent - before the parent | ||
1367 | * gets woken up by child-exit notifications. | ||
1368 | */ | ||
1369 | perf_counter_exit_task(p); | ||
1370 | |||
1374 | retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; | 1371 | retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; |
1375 | status = (p->signal->flags & SIGNAL_GROUP_EXIT) | 1372 | status = (p->signal->flags & SIGNAL_GROUP_EXIT) |
1376 | ? p->signal->group_exit_code : p->exit_code; | 1373 | ? p->signal->group_exit_code : p->exit_code; |