summaryrefslogtreecommitdiff
path: root/arch/arm/kernel/perf_event_xscale.c
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2011-03-25 17:12:37 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-03-26 10:06:09 +0000
commita737823d37666255e3e74ce84bc9611a038e0888 (patch)
tree0424691dc1af593e08877cb1ee2b2e59334f532f /arch/arm/kernel/perf_event_xscale.c
parent574b69cbb633037a9c305d2993aeb680f4a8badd (diff)
ARM: 6835/1: perf: ensure overflows aren't missed due to IRQ latency
If a counter overflows during a perf stat profiling run it may overtake the last known value of the counter: 0 prev new 0xffffffff |----------|-------|----------------------| In this case, the number of events that have occurred is (0xffffffff - prev) + new. Unfortunately, the event update code will not realise an overflow has occurred and will instead report the event delta as (new - prev) which may be considerably smaller than the real count. This patch adds an extra argument to armpmu_event_update which indicates whether or not an overflow has occurred. If an overflow has occurred then we use the maximum period of the counter to calculate the elapsed events. Acked-by: Jamie Iles <jamie@jamieiles.com> Reported-by: Ashwin Chaugule <ashwinc@codeaurora.org> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/perf_event_xscale.c')
-rw-r--r--arch/arm/kernel/perf_event_xscale.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index 28cd3b025bc3..39affbe4fdb2 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -246,7 +246,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event, hwc, idx, 1);
data.period = event->hw.last_period;
if (!armpmu_event_set_period(event, hwc, idx))
continue;
@@ -578,7 +578,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event, hwc, idx, 1);
data.period = event->hw.last_period;
if (!armpmu_event_set_period(event, hwc, idx))
continue;