diff options
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r-- | kernel/perf_counter.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f7a8ab9576e4..5c6fae4f43d8 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -146,6 +146,14 @@ static void put_ctx(struct perf_counter_context *ctx) | |||
146 | } | 146 | } |
147 | } | 147 | } |
148 | 148 | ||
149 | static void unclone_ctx(struct perf_counter_context *ctx) | ||
150 | { | ||
151 | if (ctx->parent_ctx) { | ||
152 | put_ctx(ctx->parent_ctx); | ||
153 | ctx->parent_ctx = NULL; | ||
154 | } | ||
155 | } | ||
156 | |||
149 | /* | 157 | /* |
150 | * Get the perf_counter_context for a task and lock it. | 158 | * Get the perf_counter_context for a task and lock it. |
151 | * This has to cope with with the fact that until it is locked, | 159 | * This has to cope with with the fact that until it is locked, |
@@ -1463,10 +1471,8 @@ static void perf_counter_enable_on_exec(struct task_struct *task) | |||
1463 | /* | 1471 | /* |
1464 | * Unclone this context if we enabled any counter. | 1472 | * Unclone this context if we enabled any counter. |
1465 | */ | 1473 | */ |
1466 | if (enabled && ctx->parent_ctx) { | 1474 | if (enabled) |
1467 | put_ctx(ctx->parent_ctx); | 1475 | unclone_ctx(ctx); |
1468 | ctx->parent_ctx = NULL; | ||
1469 | } | ||
1470 | 1476 | ||
1471 | spin_unlock(&ctx->lock); | 1477 | spin_unlock(&ctx->lock); |
1472 | 1478 | ||
@@ -1526,7 +1532,6 @@ __perf_counter_init_context(struct perf_counter_context *ctx, | |||
1526 | 1532 | ||
1527 | static struct perf_counter_context *find_get_context(pid_t pid, int cpu) | 1533 | static struct perf_counter_context *find_get_context(pid_t pid, int cpu) |
1528 | { | 1534 | { |
1529 | struct perf_counter_context *parent_ctx; | ||
1530 | struct perf_counter_context *ctx; | 1535 | struct perf_counter_context *ctx; |
1531 | struct perf_cpu_context *cpuctx; | 1536 | struct perf_cpu_context *cpuctx; |
1532 | struct task_struct *task; | 1537 | struct task_struct *task; |
@@ -1586,11 +1591,7 @@ static struct perf_counter_context *find_get_context(pid_t pid, int cpu) | |||
1586 | retry: | 1591 | retry: |
1587 | ctx = perf_lock_task_context(task, &flags); | 1592 | ctx = perf_lock_task_context(task, &flags); |
1588 | if (ctx) { | 1593 | if (ctx) { |
1589 | parent_ctx = ctx->parent_ctx; | 1594 | unclone_ctx(ctx); |
1590 | if (parent_ctx) { | ||
1591 | put_ctx(parent_ctx); | ||
1592 | ctx->parent_ctx = NULL; /* no longer a clone */ | ||
1593 | } | ||
1594 | spin_unlock_irqrestore(&ctx->lock, flags); | 1595 | spin_unlock_irqrestore(&ctx->lock, flags); |
1595 | } | 1596 | } |
1596 | 1597 | ||
@@ -4262,15 +4263,12 @@ void perf_counter_exit_task(struct task_struct *child) | |||
4262 | */ | 4263 | */ |
4263 | spin_lock(&child_ctx->lock); | 4264 | spin_lock(&child_ctx->lock); |
4264 | child->perf_counter_ctxp = NULL; | 4265 | child->perf_counter_ctxp = NULL; |
4265 | if (child_ctx->parent_ctx) { | 4266 | /* |
4266 | /* | 4267 | * If this context is a clone; unclone it so it can't get |
4267 | * This context is a clone; unclone it so it can't get | 4268 | * swapped to another process while we're removing all |
4268 | * swapped to another process while we're removing all | 4269 | * the counters from it. |
4269 | * the counters from it. | 4270 | */ |
4270 | */ | 4271 | unclone_ctx(child_ctx); |
4271 | put_ctx(child_ctx->parent_ctx); | ||
4272 | child_ctx->parent_ctx = NULL; | ||
4273 | } | ||
4274 | spin_unlock(&child_ctx->lock); | 4272 | spin_unlock(&child_ctx->lock); |
4275 | local_irq_restore(flags); | 4273 | local_irq_restore(flags); |
4276 | 4274 | ||