summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2011-01-26 15:38:35 +0100
committerIngo Molnar <mingo@elte.hu>2011-02-03 12:15:46 +0100
commit542e72fc90f5ed9eecb574f80f70868c7f296093 (patch)
treeb42abb2d44ed771759eee63ce00378df02d689ca /kernel
parentwatchdog: Don't change watchdog state on read of sysctl (diff)
downloadlinux-542e72fc90f5ed9eecb574f80f70868c7f296093.tar.xz
linux-542e72fc90f5ed9eecb574f80f70868c7f296093.zip
perf: Fix reading in perf_event_read()
It is quite possible for the event to have been disabled between perf_event_read() sending the IPI and the CPU servicing the IPI and calling __perf_event_read(), hence revalidate the state. Reported-by: Stephane Eranian <eranian@google.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/perf_event.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 852ae8c66502..999835b6112b 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1901,11 +1901,12 @@ static void __perf_event_read(void *info)
return;
raw_spin_lock(&ctx->lock);
- update_context_time(ctx);
+ if (ctx->is_active)
+ update_context_time(ctx);
update_event_times(event);
+ if (event->state == PERF_EVENT_STATE_ACTIVE)
+ event->pmu->read(event);
raw_spin_unlock(&ctx->lock);
-
- event->pmu->read(event);
}
static inline u64 perf_event_count(struct perf_event *event)