diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-05-25 08:45:27 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-25 08:55:01 -0400 |
commit | 6ab423e0eaca827fbd201ca4ae7d4f8573a366b2 (patch) | |
tree | 072d227934bf213adf5c0dd022369e14f273dc48 /kernel/perf_counter.c | |
parent | 771d7cde144d87f2d1fbee4da3c6234d61f7e42a (diff) |
perf_counter: Propagate inheritance failures down the fork() path
Fail fork() when we fail inheritance for some reason (-ENOMEM most likely).
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: John Kacur <jkacur@redhat.com>
LKML-Reference: <20090525124600.324656474@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r-- | kernel/perf_counter.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 217dbcce2ebd..7a7a144870ef 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -3434,18 +3434,23 @@ again: | |||
3434 | /* | 3434 | /* |
3435 | * Initialize the perf_counter context in task_struct | 3435 | * Initialize the perf_counter context in task_struct |
3436 | */ | 3436 | */ |
3437 | void perf_counter_init_task(struct task_struct *child) | 3437 | int perf_counter_init_task(struct task_struct *child) |
3438 | { | 3438 | { |
3439 | struct perf_counter_context *child_ctx, *parent_ctx; | 3439 | struct perf_counter_context *child_ctx, *parent_ctx; |
3440 | struct perf_counter *counter; | 3440 | struct perf_counter *counter; |
3441 | struct task_struct *parent = current; | 3441 | struct task_struct *parent = current; |
3442 | int inherited_all = 1; | 3442 | int inherited_all = 1; |
3443 | int ret = 0; | ||
3443 | 3444 | ||
3444 | child->perf_counter_ctxp = NULL; | 3445 | child->perf_counter_ctxp = NULL; |
3445 | 3446 | ||
3446 | mutex_init(&child->perf_counter_mutex); | 3447 | mutex_init(&child->perf_counter_mutex); |
3447 | INIT_LIST_HEAD(&child->perf_counter_list); | 3448 | INIT_LIST_HEAD(&child->perf_counter_list); |
3448 | 3449 | ||
3450 | parent_ctx = parent->perf_counter_ctxp; | ||
3451 | if (likely(!parent_ctx || !parent_ctx->nr_counters)) | ||
3452 | return 0; | ||
3453 | |||
3449 | /* | 3454 | /* |
3450 | * This is executed from the parent task context, so inherit | 3455 | * This is executed from the parent task context, so inherit |
3451 | * counters that have been marked for cloning. | 3456 | * counters that have been marked for cloning. |
@@ -3454,11 +3459,7 @@ void perf_counter_init_task(struct task_struct *child) | |||
3454 | 3459 | ||
3455 | child_ctx = kmalloc(sizeof(struct perf_counter_context), GFP_KERNEL); | 3460 | child_ctx = kmalloc(sizeof(struct perf_counter_context), GFP_KERNEL); |
3456 | if (!child_ctx) | 3461 | if (!child_ctx) |
3457 | return; | 3462 | return -ENOMEM; |
3458 | |||
3459 | parent_ctx = parent->perf_counter_ctxp; | ||
3460 | if (likely(!parent_ctx || !parent_ctx->nr_counters)) | ||
3461 | return; | ||
3462 | 3463 | ||
3463 | __perf_counter_init_context(child_ctx, child); | 3464 | __perf_counter_init_context(child_ctx, child); |
3464 | child->perf_counter_ctxp = child_ctx; | 3465 | child->perf_counter_ctxp = child_ctx; |
@@ -3482,8 +3483,9 @@ void perf_counter_init_task(struct task_struct *child) | |||
3482 | continue; | 3483 | continue; |
3483 | } | 3484 | } |
3484 | 3485 | ||
3485 | if (inherit_group(counter, parent, | 3486 | ret = inherit_group(counter, parent, parent_ctx, |
3486 | parent_ctx, child, child_ctx)) { | 3487 | child, child_ctx); |
3488 | if (ret) { | ||
3487 | inherited_all = 0; | 3489 | inherited_all = 0; |
3488 | break; | 3490 | break; |
3489 | } | 3491 | } |
@@ -3505,6 +3507,8 @@ void perf_counter_init_task(struct task_struct *child) | |||
3505 | } | 3507 | } |
3506 | 3508 | ||
3507 | mutex_unlock(&parent_ctx->mutex); | 3509 | mutex_unlock(&parent_ctx->mutex); |
3510 | |||
3511 | return ret; | ||
3508 | } | 3512 | } |
3509 | 3513 | ||
3510 | static void __cpuinit perf_counter_init_cpu(int cpu) | 3514 | static void __cpuinit perf_counter_init_cpu(int cpu) |