Commit 1cade527 authored by Athira Rajeev's avatar Athira Rajeev Committed by Michael Ellerman

powerpc/perf: BHRB control to disable BHRB logic when not used

PowerISA v3.1 has few updates for the Branch History Rolling
Buffer(BHRB).

BHRB disable is controlled via Monitor Mode Control Register A (MMCRA)
bit, namely "BHRB Recording Disable (BHRBRD)". This field controls
whether BHRB entries are written when BHRB recording is enabled by
other bits. This patch implements support for this BHRB disable bit.
By setting 0b1 to this bit will disable the BHRB and by setting 0b0 to
this bit will have BHRB enabled. This addresses backward
compatibility (for older OS), since this bit will be cleared and
hardware will be writing to BHRB by default.

This patch addresses changes to set MMCRA (BHRBRD) at boot for
power10 (there by the core will run faster) and enable this feature
only on runtime ie, on explicit need from user. Also save/restore
MMCRA in the restore path of state-loss idle state to make sure we
keep BHRB disabled if it was not enabled on request at runtime.
Signed-off-by: default avatarAthira Rajeev <atrajeev@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1594996707-3727-12-git-send-email-atrajeev@linux.vnet.ibm.com
parent 80350a4b
...@@ -1219,7 +1219,7 @@ static void write_mmcr0(struct cpu_hw_events *cpuhw, unsigned long mmcr0) ...@@ -1219,7 +1219,7 @@ static void write_mmcr0(struct cpu_hw_events *cpuhw, unsigned long mmcr0)
static void power_pmu_disable(struct pmu *pmu) static void power_pmu_disable(struct pmu *pmu)
{ {
struct cpu_hw_events *cpuhw; struct cpu_hw_events *cpuhw;
unsigned long flags, mmcr0, val; unsigned long flags, mmcr0, val, mmcra;
if (!ppmu) if (!ppmu)
return; return;
...@@ -1252,12 +1252,24 @@ static void power_pmu_disable(struct pmu *pmu) ...@@ -1252,12 +1252,24 @@ static void power_pmu_disable(struct pmu *pmu)
mb(); mb();
isync(); isync();
val = mmcra = cpuhw->mmcr.mmcra;
/* /*
* Disable instruction sampling if it was enabled * Disable instruction sampling if it was enabled
*/ */
if (cpuhw->mmcr.mmcra & MMCRA_SAMPLE_ENABLE) { if (cpuhw->mmcr.mmcra & MMCRA_SAMPLE_ENABLE)
mtspr(SPRN_MMCRA, val &= ~MMCRA_SAMPLE_ENABLE;
cpuhw->mmcr.mmcra & ~MMCRA_SAMPLE_ENABLE);
/* Disable BHRB via mmcra (BHRBRD) for p10 */
if (ppmu->flags & PPMU_ARCH_31)
val |= MMCRA_BHRB_DISABLE;
/*
* Write SPRN_MMCRA if mmcra has either disabled
* instruction sampling or BHRB.
*/
if (val != mmcra) {
mtspr(SPRN_MMCRA, mmcra);
mb(); mb();
isync(); isync();
} }
......
...@@ -404,6 +404,13 @@ int isa207_compute_mmcr(u64 event[], int n_ev, ...@@ -404,6 +404,13 @@ int isa207_compute_mmcr(u64 event[], int n_ev,
mmcra = mmcr1 = mmcr2 = mmcr3 = 0; mmcra = mmcr1 = mmcr2 = mmcr3 = 0;
/*
* Disable bhrb unless explicitly requested
* by setting MMCRA (BHRBRD) bit.
*/
if (cpu_has_feature(CPU_FTR_ARCH_31))
mmcra |= MMCRA_BHRB_DISABLE;
/* Second pass: assign PMCs, set all MMCR1 fields */ /* Second pass: assign PMCs, set all MMCR1 fields */
for (i = 0; i < n_ev; ++i) { for (i = 0; i < n_ev; ++i) {
pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK;
...@@ -479,6 +486,11 @@ int isa207_compute_mmcr(u64 event[], int n_ev, ...@@ -479,6 +486,11 @@ int isa207_compute_mmcr(u64 event[], int n_ev,
mmcra |= val << MMCRA_IFM_SHIFT; mmcra |= val << MMCRA_IFM_SHIFT;
} }
/* set MMCRA (BHRBRD) to 0 if there is user request for BHRB */
if (cpu_has_feature(CPU_FTR_ARCH_31) &&
(has_branch_stack(pevents[i]) || (event[i] & EVENT_WANTS_BHRB)))
mmcra &= ~MMCRA_BHRB_DISABLE;
if (pevents[i]->attr.exclude_user) if (pevents[i]->attr.exclude_user)
mmcr2 |= MMCR2_FCP(pmc); mmcr2 |= MMCR2_FCP(pmc);
......
...@@ -611,6 +611,7 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) ...@@ -611,6 +611,7 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
unsigned long srr1; unsigned long srr1;
unsigned long pls; unsigned long pls;
unsigned long mmcr0 = 0; unsigned long mmcr0 = 0;
unsigned long mmcra = 0;
struct p9_sprs sprs = {}; /* avoid false used-uninitialised */ struct p9_sprs sprs = {}; /* avoid false used-uninitialised */
bool sprs_saved = false; bool sprs_saved = false;
...@@ -657,6 +658,21 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) ...@@ -657,6 +658,21 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
*/ */
mmcr0 = mfspr(SPRN_MMCR0); mmcr0 = mfspr(SPRN_MMCR0);
} }
if (cpu_has_feature(CPU_FTR_ARCH_31)) {
/*
* POWER10 uses MMCRA (BHRBRD) as BHRB disable bit.
* If the user hasn't asked for the BHRB to be
* written, the value of MMCRA[BHRBRD] is 1.
* On wakeup from stop, MMCRA[BHRBD] will be 0,
* since it is previleged resource and will be lost.
* Thus, if we do not save and restore the MMCRA[BHRBD],
* hardware will be needlessly writing to the BHRB
* in problem mode.
*/
mmcra = mfspr(SPRN_MMCRA);
}
if ((psscr & PSSCR_RL_MASK) >= pnv_first_spr_loss_level) { if ((psscr & PSSCR_RL_MASK) >= pnv_first_spr_loss_level) {
sprs.lpcr = mfspr(SPRN_LPCR); sprs.lpcr = mfspr(SPRN_LPCR);
sprs.hfscr = mfspr(SPRN_HFSCR); sprs.hfscr = mfspr(SPRN_HFSCR);
...@@ -700,8 +716,6 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) ...@@ -700,8 +716,6 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
WARN_ON_ONCE(mfmsr() & (MSR_IR|MSR_DR)); WARN_ON_ONCE(mfmsr() & (MSR_IR|MSR_DR));
if ((srr1 & SRR1_WAKESTATE) != SRR1_WS_NOLOSS) { if ((srr1 & SRR1_WAKESTATE) != SRR1_WS_NOLOSS) {
unsigned long mmcra;
/* /*
* We don't need an isync after the mtsprs here because the * We don't need an isync after the mtsprs here because the
* upcoming mtmsrd is execution synchronizing. * upcoming mtmsrd is execution synchronizing.
...@@ -721,6 +735,10 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) ...@@ -721,6 +735,10 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
mtspr(SPRN_MMCR0, mmcr0); mtspr(SPRN_MMCR0, mmcr0);
} }
/* Reload MMCRA to restore BHRB disable bit for POWER10 */
if (cpu_has_feature(CPU_FTR_ARCH_31))
mtspr(SPRN_MMCRA, mmcra);
/* /*
* DD2.2 and earlier need to set then clear bit 60 in MMCRA * DD2.2 and earlier need to set then clear bit 60 in MMCRA
* to ensure the PMU starts running. * to ensure the PMU starts running.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment