From 50e6f3e9a90d04d7370fe657fff6ab401fca689b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 3 Jun 2009 19:40:36 +1000 Subject: [PATCH] --- yaml --- r: 147625 b: refs/heads/master c: dcd945e0d8a6d654e3e1de51faea9f98f1504aa5 h: refs/heads/master i: 147623: 776327be9ecf95e15fbc561f14aa8eb202d4ea33 v: v3 --- [refs] | 2 +- trunk/arch/powerpc/kernel/perf_counter.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index d40f4085e790..c05a8e061b77 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6984efb692e97ce5f75f26e595685c04c2061bac +refs/heads/master: dcd945e0d8a6d654e3e1de51faea9f98f1504aa5 diff --git a/trunk/arch/powerpc/kernel/perf_counter.c b/trunk/arch/powerpc/kernel/perf_counter.c index ea54686cb787..4cc4ac5c791c 100644 --- a/trunk/arch/powerpc/kernel/perf_counter.c +++ b/trunk/arch/powerpc/kernel/perf_counter.c @@ -372,16 +372,28 @@ static void write_mmcr0(struct cpu_hw_counters *cpuhw, unsigned long mmcr0) /* * Write MMCR0, then read PMC5 and PMC6 immediately. + * To ensure we don't get a performance monitor interrupt + * between writing MMCR0 and freezing/thawing the limited + * counters, we first write MMCR0 with the counter overflow + * interrupt enable bits turned off. */ asm volatile("mtspr %3,%2; mfspr %0,%4; mfspr %1,%5" : "=&r" (pmc5), "=&r" (pmc6) - : "r" (mmcr0), "i" (SPRN_MMCR0), + : "r" (mmcr0 & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)), + "i" (SPRN_MMCR0), "i" (SPRN_PMC5), "i" (SPRN_PMC6)); if (mmcr0 & MMCR0_FC) freeze_limited_counters(cpuhw, pmc5, pmc6); else thaw_limited_counters(cpuhw, pmc5, pmc6); + + /* + * Write the full MMCR0 including the counter overflow interrupt + * enable bits, if necessary. + */ + if (mmcr0 & (MMCR0_PMC1CE | MMCR0_PMCjCE)) + mtspr(SPRN_MMCR0, mmcr0); } /* @@ -1108,7 +1120,7 @@ static void perf_counter_interrupt(struct pt_regs *regs) for (i = 0; i < cpuhw->n_counters; ++i) { counter = cpuhw->counter[i]; - if (is_limited_pmc(counter->hw.idx)) + if (!counter->hw.idx || is_limited_pmc(counter->hw.idx)) continue; val = read_pmc(counter->hw.idx); if ((int)val < 0) {