| From b50a6c584bb47b370f84bfd746770c0bbe7129b7 Mon Sep 17 00:00:00 2001 |
| From: Joel Stanley <joel@jms.id.au> |
| Date: Tue, 8 Jul 2014 16:08:22 +0930 |
| Subject: powerpc/perf: Clear MMCR2 when enabling PMU |
| |
| From: Joel Stanley <joel@jms.id.au> |
| |
| commit b50a6c584bb47b370f84bfd746770c0bbe7129b7 upstream. |
| |
| On POWER8 when switching to a KVM guest we set bits in MMCR2 to freeze |
| the PMU counters. Aside from on boot they are then never reset, |
| resulting in stuck perf counters for any user in the guest or host. |
| |
| We now set MMCR2 to 0 whenever enabling the PMU, which provides a sane |
| state for perf to use the PMU counters under either the guest or the |
| host. |
| |
| This was manifesting as a bug with ppc64_cpu --frequency: |
| |
| $ sudo ppc64_cpu --frequency |
| WARNING: couldn't run on cpu 0 |
| WARNING: couldn't run on cpu 8 |
| ... |
| WARNING: couldn't run on cpu 144 |
| WARNING: couldn't run on cpu 152 |
| min: 18446744073.710 GHz (cpu -1) |
| max: 0.000 GHz (cpu -1) |
| avg: 0.000 GHz |
| |
| The command uses a perf counter to measure CPU cycles over a fixed |
| amount of time, in order to approximate the frequency of the machine. |
| The counters were returning zero once a guest was started, regardless of |
| weather it was still running or had been shut down. |
| |
| By dumping the value of MMCR2, it was observed that once a guest is |
| running MMCR2 is set to 1s - which stops counters from running: |
| |
| $ sudo sh -c 'echo p > /proc/sysrq-trigger' |
| CPU: 0 PMU registers, ppmu = POWER8 n_counters = 6 |
| PMC1: 5b635e38 PMC2: 00000000 PMC3: 00000000 PMC4: 00000000 |
| PMC5: 1bf5a646 PMC6: 5793d378 PMC7: deadbeef PMC8: deadbeef |
| MMCR0: 0000000080000000 MMCR1: 000000001e000000 MMCRA: 0000040000000000 |
| MMCR2: fffffffffffffc00 EBBHR: 0000000000000000 |
| EBBRR: 0000000000000000 BESCR: 0000000000000000 |
| SIAR: 00000000000a51cc SDAR: c00000000fc40000 SIER: 0000000001000000 |
| |
| This is done unconditionally in book3s_hv_interrupts.S upon entering the |
| guest, and the original value is only save/restored if the host has |
| indicated it was using the PMU. This is okay, however the user of the |
| PMU needs to ensure that it is in a defined state when it starts using |
| it. |
| |
| Fixes: e05b9b9e5c10 ("powerpc/perf: Power8 PMU support") |
| Signed-off-by: Joel Stanley <joel@jms.id.au> |
| Acked-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/powerpc/perf/core-book3s.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/arch/powerpc/perf/core-book3s.c |
| +++ b/arch/powerpc/perf/core-book3s.c |
| @@ -1167,6 +1167,9 @@ static void power_pmu_enable(struct pmu |
| |
| write_mmcr0(cpuhw, mmcr0); |
| |
| + if (ppmu->flags & PPMU_ARCH_207S) |
| + mtspr(SPRN_MMCR2, 0); |
| + |
| /* |
| * Enable instruction sampling if necessary |
| */ |