From: tip-bot for Peter Zijlstra <a.p.zijlstra@chello.nl>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, paulus@samba.org, hpa@zytor.com,
mingo@redhat.com, a.p.zijlstra@chello.nl,
markus.t.metzger@intel.com, tglx@linutronix.de, mingo@elte.hu
Subject: [tip:perfcounters/core] perf_counter: Fix a race on perf_counter_ctx
Date: Sat, 8 Aug 2009 11:52:55 GMT [thread overview]
Message-ID: <tip-c3eeded22c6aa759e51d04469b9c42c4b9d2ac01@git.kernel.org> (raw)
In-Reply-To: <1249667341.17467.5.camel@twins>
Commit-ID: c3eeded22c6aa759e51d04469b9c42c4b9d2ac01
Gitweb: http://git.kernel.org/tip/c3eeded22c6aa759e51d04469b9c42c4b9d2ac01
Author: Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Fri, 7 Aug 2009 19:49:01 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Sat, 8 Aug 2009 13:49:54 +0200
perf_counter: Fix a race on perf_counter_ctx
While extending perfcounters with BTS hw-tracing, Markus
Metzger managed to trigger this warning:
[ 995.557128] WARNING: at kernel/perf_counter.c:1191 __perf_counter_task_sched_out+0x48/0x6b()
triggers because commit
9f498cc5be7e013d8d6e4c616980ed0ffc8680d2 (perf_counter: Full
task tracing) removed clearing of tsk->perf_counter_ctxp out
from under ctx->lock which introduced a race (against
perf_lock_task_context).
Move it back and deal with the exit notification by explicitly
passing along the former task context.
Reported-by: Markus T Metzger <markus.t.metzger@intel.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1249667341.17467.5.camel@twins>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/perf_counter.c | 30 +++++++++++++++---------------
1 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 0023105..546e62d 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -2850,7 +2850,8 @@ perf_counter_read_event(struct perf_counter *counter,
*/
struct perf_task_event {
- struct task_struct *task;
+ struct task_struct *task;
+ struct perf_counter_context *task_ctx;
struct {
struct perf_event_header header;
@@ -2910,24 +2911,23 @@ static void perf_counter_task_ctx(struct perf_counter_context *ctx,
static void perf_counter_task_event(struct perf_task_event *task_event)
{
struct perf_cpu_context *cpuctx;
- struct perf_counter_context *ctx;
+ struct perf_counter_context *ctx = task_event->task_ctx;
cpuctx = &get_cpu_var(perf_cpu_context);
perf_counter_task_ctx(&cpuctx->ctx, task_event);
put_cpu_var(perf_cpu_context);
rcu_read_lock();
- /*
- * doesn't really matter which of the child contexts the
- * events ends up in.
- */
- ctx = rcu_dereference(current->perf_counter_ctxp);
+ if (!ctx)
+ ctx = rcu_dereference(task_event->task->perf_counter_ctxp);
if (ctx)
perf_counter_task_ctx(ctx, task_event);
rcu_read_unlock();
}
-static void perf_counter_task(struct task_struct *task, int new)
+static void perf_counter_task(struct task_struct *task,
+ struct perf_counter_context *task_ctx,
+ int new)
{
struct perf_task_event task_event;
@@ -2937,8 +2937,9 @@ static void perf_counter_task(struct task_struct *task, int new)
return;
task_event = (struct perf_task_event){
- .task = task,
- .event = {
+ .task = task,
+ .task_ctx = task_ctx,
+ .event = {
.header = {
.type = new ? PERF_EVENT_FORK : PERF_EVENT_EXIT,
.misc = 0,
@@ -2956,7 +2957,7 @@ static void perf_counter_task(struct task_struct *task, int new)
void perf_counter_fork(struct task_struct *task)
{
- perf_counter_task(task, 1);
+ perf_counter_task(task, NULL, 1);
}
/*
@@ -4310,7 +4311,7 @@ void perf_counter_exit_task(struct task_struct *child)
unsigned long flags;
if (likely(!child->perf_counter_ctxp)) {
- perf_counter_task(child, 0);
+ perf_counter_task(child, NULL, 0);
return;
}
@@ -4330,6 +4331,7 @@ void perf_counter_exit_task(struct task_struct *child)
* incremented the context's refcount before we do put_ctx below.
*/
spin_lock(&child_ctx->lock);
+ child->perf_counter_ctxp = NULL;
/*
* If this context is a clone; unclone it so it can't get
* swapped to another process while we're removing all
@@ -4343,9 +4345,7 @@ void perf_counter_exit_task(struct task_struct *child)
* won't get any samples after PERF_EVENT_EXIT. We can however still
* get a few PERF_EVENT_READ events.
*/
- perf_counter_task(child, 0);
-
- child->perf_counter_ctxp = NULL;
+ perf_counter_task(child, child_ctx, 0);
/*
* We can recurse on the same lock type through:
next prev parent reply other threads:[~2009-08-08 11:54 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-21 13:56 [patch] x86, perf_counter, bts: add bts to perf_counter Markus Metzger
2009-08-04 10:24 ` Peter Zijlstra
2009-08-04 11:14 ` Ingo Molnar
2009-08-04 11:35 ` Ingo Molnar
2009-08-05 11:10 ` Metzger, Markus T
2009-08-07 7:29 ` Metzger, Markus T
2009-08-07 8:21 ` Peter Zijlstra
2009-08-07 10:18 ` Metzger, Markus T
2009-08-07 10:29 ` Peter Zijlstra
2009-08-07 12:18 ` Metzger, Markus T
2009-08-07 13:05 ` Peter Zijlstra
2009-08-07 10:31 ` Ingo Molnar
2009-08-07 10:36 ` Ingo Molnar
2009-08-07 10:57 ` Metzger, Markus T
2009-08-07 11:17 ` Metzger, Markus T
2009-08-07 11:24 ` Ingo Molnar
2009-08-07 11:33 ` Ingo Molnar
2009-08-07 17:49 ` [PATCH] perf_counter: Fix a race on perf_counter_ctx Peter Zijlstra
2009-08-08 11:52 ` tip-bot for Peter Zijlstra [this message]
2009-08-08 12:03 ` Ingo Molnar
2009-08-10 12:33 ` Metzger, Markus T
2009-08-10 12:59 ` Peter Zijlstra
2009-08-10 13:46 ` Ingo Molnar
2009-08-11 6:33 ` Metzger, Markus T
2009-08-11 8:59 ` Metzger, Markus T
2009-08-18 12:49 ` Metzger, Markus T
2009-08-18 12:59 ` Peter Zijlstra
2009-08-18 12:59 ` Peter Zijlstra
2009-08-18 13:20 ` Metzger, Markus T
2009-08-18 13:37 ` Peter Zijlstra
2009-08-18 13:54 ` Metzger, Markus T
2009-08-18 14:00 ` Ingo Molnar
2009-08-18 14:15 ` Metzger, Markus T
2009-08-28 9:56 ` Metzger, Markus T
2009-09-01 11:17 ` [discuss] BTS overflow handling, was: " Metzger, Markus T
2009-09-01 13:00 ` Peter Zijlstra
2009-09-01 13:09 ` Ingo Molnar
2009-09-01 13:32 ` Metzger, Markus T
2009-09-01 13:53 ` Peter Zijlstra
2009-09-01 14:27 ` Metzger, Markus T
2009-09-01 14:35 ` Peter Zijlstra
2009-09-03 14:25 ` Metzger, Markus T
2009-08-18 14:01 ` Peter Zijlstra
2009-08-18 14:19 ` Metzger, Markus T
2009-08-09 11:10 ` [tip:perfcounters/core] " tip-bot for Peter Zijlstra
2009-08-07 11:26 ` [patch] x86, perf_counter, bts: add bts to perf_counter Ingo Molnar
2009-08-07 11:29 ` Ingo Molnar
2009-08-07 12:14 ` Metzger, Markus T
2009-08-07 11:19 ` Ingo Molnar
2009-08-07 11:34 ` Metzger, Markus T
2009-08-07 11:37 ` Metzger, Markus T
2009-08-04 11:37 ` [tip:perfcounters/urgent] x86, perf_counter, bts: Add BTS support to perfcounters tip-bot for Markus Metzger
2009-08-07 10:10 ` [tip:perfcounters/core] " tip-bot for Markus Metzger
2009-08-08 11:43 ` tip-bot for Markus Metzger
2009-08-08 11:53 ` tip-bot for Markus Metzger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-c3eeded22c6aa759e51d04469b9c42c4b9d2ac01@git.kernel.org \
--to=a.p.zijlstra@chello.nl \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=markus.t.metzger@intel.com \
--cc=mingo@elte.hu \
--cc=mingo@redhat.com \
--cc=paulus@samba.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.