diff options
author | Tom Huynh <tom.huynh@freescale.com> | 2015-01-20 23:19:50 +0100 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2015-01-30 03:05:56 +0100 |
commit | d2caa3cebda8b626336e100b80a0ed6f909dccab (patch) | |
tree | 1f72536b25f7bcaa9e891a85891f9a060bcdaeb1 /arch/powerpc/perf/core-fsl-emb.c | |
parent | powerpc: Remove duplicate tlbcam_index declarations (diff) | |
download | linux-d2caa3cebda8b626336e100b80a0ed6f909dccab.tar.xz linux-d2caa3cebda8b626336e100b80a0ed6f909dccab.zip |
powerpc/perf: fix fsl_emb_pmu_start to write correct pmc value
PMCs on PowerPC increases towards 0x80000000 and triggers an overflow
interrupt when the msb is set to collect a sample. Therefore, to setup
for the next sample collection, pmu_start should set the pmc value to
0x80000000 - left instead of left which incorrectly delays the next
overflow interrupt. Same as commit 9a45a9407c69 ("powerpc/perf:
power_pmu_start restores incorrect values, breaking frequency events")
for book3s.
Signed-off-by: Tom Huynh <tom.huynh@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch/powerpc/perf/core-fsl-emb.c')
-rw-r--r-- | arch/powerpc/perf/core-fsl-emb.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c index 4acaea01fe03..e9fe904b6538 100644 --- a/arch/powerpc/perf/core-fsl-emb.c +++ b/arch/powerpc/perf/core-fsl-emb.c @@ -389,6 +389,7 @@ static void fsl_emb_pmu_del(struct perf_event *event, int flags) static void fsl_emb_pmu_start(struct perf_event *event, int ef_flags) { unsigned long flags; + unsigned long val; s64 left; if (event->hw.idx < 0 || !event->hw.sample_period) @@ -405,7 +406,10 @@ static void fsl_emb_pmu_start(struct perf_event *event, int ef_flags) event->hw.state = 0; left = local64_read(&event->hw.period_left); - write_pmc(event->hw.idx, left); + val = 0; + if (left < 0x80000000L) + val = 0x80000000L - left; + write_pmc(event->hw.idx, val); perf_event_update_userpage(event); perf_pmu_enable(event->pmu); |