aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2013-05-06 12:27:17 -0400
committerIngo Molnar <mingo@kernel.org>2013-05-07 07:17:28 -0400
commit524eff183f51d080a83b348d0ea97c08b3607b9a (patch)
treef82d50daa9e5cc77152f78c08d25ba92cc7b32de /kernel
parent534c97b0950b1967bca1c753aeaed32f5db40264 (diff)
perf: Fix EXIT event notification
The perf_event_task_ctx() function needs to be called with preemption disabled, since it's checking for currently scheduled cpu against event cpu. We disable preemption for task related perf event context if there's one defined, leaving up to the chance which cpu it gets scheduled in. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Stephane Eranian <eranian@google.com> Cc: Borislav Petkov <bp@alien8.de> Link: http://lkml.kernel.org/r/1367857638-27631-2-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/events/core.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 6b41c1899a8b..38b68a05c3c6 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4474,7 +4474,7 @@ static void perf_event_task_ctx(struct perf_event_context *ctx,
4474static void perf_event_task_event(struct perf_task_event *task_event) 4474static void perf_event_task_event(struct perf_task_event *task_event)
4475{ 4475{
4476 struct perf_cpu_context *cpuctx; 4476 struct perf_cpu_context *cpuctx;
4477 struct perf_event_context *ctx; 4477 struct perf_event_context *ctx, *task_ctx = task_event->task_ctx;
4478 struct pmu *pmu; 4478 struct pmu *pmu;
4479 int ctxn; 4479 int ctxn;
4480 4480
@@ -4485,20 +4485,22 @@ static void perf_event_task_event(struct perf_task_event *task_event)
4485 goto next; 4485 goto next;
4486 perf_event_task_ctx(&cpuctx->ctx, task_event); 4486 perf_event_task_ctx(&cpuctx->ctx, task_event);
4487 4487
4488 ctx = task_event->task_ctx; 4488 if (task_ctx)
4489 if (!ctx) { 4489 goto next;
4490 ctxn = pmu->task_ctx_nr; 4490 ctxn = pmu->task_ctx_nr;
4491 if (ctxn < 0) 4491 if (ctxn < 0)
4492 goto next; 4492 goto next;
4493 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); 4493 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
4494 if (ctx) 4494 if (ctx)
4495 perf_event_task_ctx(ctx, task_event); 4495 perf_event_task_ctx(ctx, task_event);
4496 }
4497next: 4496next:
4498 put_cpu_ptr(pmu->pmu_cpu_context); 4497 put_cpu_ptr(pmu->pmu_cpu_context);
4499 } 4498 }
4500 if (task_event->task_ctx) 4499 if (task_ctx) {
4501 perf_event_task_ctx(task_event->task_ctx, task_event); 4500 preempt_disable();
4501 perf_event_task_ctx(task_ctx, task_event);
4502 preempt_enable();
4503 }
4502 4504
4503 rcu_read_unlock(); 4505 rcu_read_unlock();
4504} 4506}