diff options
| author | Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> | 2009-12-08 22:29:44 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-12-09 03:56:27 -0500 |
| commit | b93f7978ad6b46133e9453b90ccc057dc2429e75 (patch) | |
| tree | f3420ebd5fa80ddb1a4c3e302a64861146104385 | |
| parent | aa5452d70c0d559310598b243b8b1033c10056e7 (diff) | |
perf_event: Allocate children's perf_event_ctxp at the right time
In current code, children task will allocate memory for
'child->perf_event_ctxp' if the parent is counted, we can
do it only if the parent allowed children inherit it.
It can save memory and reduce overhead.
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Reviewed-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <4B1F19A8.5040805@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | kernel/perf_event.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 2b06c45bfba9..77641ae6b23f 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
| @@ -5083,7 +5083,7 @@ again: | |||
| 5083 | */ | 5083 | */ |
| 5084 | int perf_event_init_task(struct task_struct *child) | 5084 | int perf_event_init_task(struct task_struct *child) |
| 5085 | { | 5085 | { |
| 5086 | struct perf_event_context *child_ctx, *parent_ctx; | 5086 | struct perf_event_context *child_ctx = NULL, *parent_ctx; |
| 5087 | struct perf_event_context *cloned_ctx; | 5087 | struct perf_event_context *cloned_ctx; |
| 5088 | struct perf_event *event; | 5088 | struct perf_event *event; |
| 5089 | struct task_struct *parent = current; | 5089 | struct task_struct *parent = current; |
| @@ -5099,20 +5099,6 @@ int perf_event_init_task(struct task_struct *child) | |||
| 5099 | return 0; | 5099 | return 0; |
| 5100 | 5100 | ||
| 5101 | /* | 5101 | /* |
| 5102 | * This is executed from the parent task context, so inherit | ||
| 5103 | * events that have been marked for cloning. | ||
| 5104 | * First allocate and initialize a context for the child. | ||
| 5105 | */ | ||
| 5106 | |||
| 5107 | child_ctx = kzalloc(sizeof(struct perf_event_context), GFP_KERNEL); | ||
| 5108 | if (!child_ctx) | ||
| 5109 | return -ENOMEM; | ||
| 5110 | |||
| 5111 | __perf_event_init_context(child_ctx, child); | ||
| 5112 | child->perf_event_ctxp = child_ctx; | ||
| 5113 | get_task_struct(child); | ||
| 5114 | |||
| 5115 | /* | ||
| 5116 | * If the parent's context is a clone, pin it so it won't get | 5102 | * If the parent's context is a clone, pin it so it won't get |
| 5117 | * swapped under us. | 5103 | * swapped under us. |
| 5118 | */ | 5104 | */ |
| @@ -5142,6 +5128,26 @@ int perf_event_init_task(struct task_struct *child) | |||
| 5142 | continue; | 5128 | continue; |
| 5143 | } | 5129 | } |
| 5144 | 5130 | ||
| 5131 | if (!child->perf_event_ctxp) { | ||
| 5132 | /* | ||
| 5133 | * This is executed from the parent task context, so | ||
| 5134 | * inherit events that have been marked for cloning. | ||
| 5135 | * First allocate and initialize a context for the | ||
| 5136 | * child. | ||
| 5137 | */ | ||
| 5138 | |||
| 5139 | child_ctx = kzalloc(sizeof(struct perf_event_context), | ||
| 5140 | GFP_KERNEL); | ||
| 5141 | if (!child_ctx) { | ||
| 5142 | ret = -ENOMEM; | ||
| 5143 | goto exit; | ||
| 5144 | } | ||
| 5145 | |||
| 5146 | __perf_event_init_context(child_ctx, child); | ||
| 5147 | child->perf_event_ctxp = child_ctx; | ||
| 5148 | get_task_struct(child); | ||
| 5149 | } | ||
| 5150 | |||
| 5145 | ret = inherit_group(event, parent, parent_ctx, | 5151 | ret = inherit_group(event, parent, parent_ctx, |
| 5146 | child, child_ctx); | 5152 | child, child_ctx); |
| 5147 | if (ret) { | 5153 | if (ret) { |
| @@ -5170,6 +5176,7 @@ int perf_event_init_task(struct task_struct *child) | |||
| 5170 | get_ctx(child_ctx->parent_ctx); | 5176 | get_ctx(child_ctx->parent_ctx); |
| 5171 | } | 5177 | } |
| 5172 | 5178 | ||
| 5179 | exit: | ||
| 5173 | mutex_unlock(&parent_ctx->mutex); | 5180 | mutex_unlock(&parent_ctx->mutex); |
| 5174 | 5181 | ||
| 5175 | perf_unpin_context(parent_ctx); | 5182 | perf_unpin_context(parent_ctx); |
