[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1531235533-8958-1-git-send-email-kan.liang@linux.intel.com>
Date: Tue, 10 Jul 2018 08:12:13 -0700
From: kan.liang@...ux.intel.com
To: peterz@...radead.org, tglx@...utronix.de, mingo@...hat.com,
linux-kernel@...r.kernel.org
Cc: ak@...ux.intel.com, sunil.k.pandey@...el.com,
Kan Liang <kan.liang@...ux.intel.com>
Subject: [PATCH] perf/x86/intel: Disable LBR while checking LBR related MSRs
From: Kan Liang <kan.liang@...ux.intel.com>
Skylake server has LBR support on hardware, but the support is
mistakenly and permanently disabled for perf on some machines,
for example:
$ dmesg | grep -i PMU
[ 0.055783] Performance Events: PEBS fmt3+, Skylake events,
full-width counters, Intel PMU driver.
Current code checks the LBR related MSRs before enabling LBR support
for perf. The code reads the current value of LBR MSR, change it and
read it back to see if it matches. If it doesn't match, LBR support
will be disabled permanently.
On some machines, the LBR bit of MSR_IA32_DEBUGCTLMSR may be set while
checking. If so, hardware may changes the LBR MSRs implicitly, which
misleading the check.
Explicitly disable LBR while checking LBR related MSRs. Restore the old
value after checking if it's changed.
$ dmesg | grep -i PMU
[ 0.064000] Performance Events: PEBS fmt3+, Skylake events, 32-deep
LBR, full-width counters, Intel PMU driver.
$ perf record -a -e cycles:u -j any,u ls
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.109 MB perf.data (77 samples) ]
Reported-by: Pandey, Sunil K <sunil.k.pandey@...el.com>
Signed-off-by: Kan Liang <kan.liang@...ux.intel.com>
Tested-by: Pandey, Sunil K <sunil.k.pandey@...el.com>
---
arch/x86/events/intel/core.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 707b2a9..d01e801 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3878,6 +3878,7 @@ __init int intel_pmu_init(void)
unsigned int unused;
struct extra_reg *er;
int version, i;
+ u64 debugctl;
char *name;
if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
@@ -4382,6 +4383,14 @@ __init int intel_pmu_init(void)
}
/*
+ * LBR bit may be set on some machines.
+ * Disable LBR while checking LBR related MSRs.
+ */
+ debugctl = get_debugctlmsr();
+ if (debugctl & DEBUGCTLMSR_LBR)
+ update_debugctlmsr(debugctl & ~DEBUGCTLMSR_LBR);
+
+ /*
* Access LBR MSR may cause #GP under certain circumstances.
* E.g. KVM doesn't support LBR MSR
* Check all LBT MSR here.
@@ -4395,6 +4404,10 @@ __init int intel_pmu_init(void)
x86_pmu.lbr_nr = 0;
}
+ /* Restore the old value if changed */
+ if (debugctl & DEBUGCTLMSR_LBR)
+ update_debugctlmsr(debugctl);
+
x86_pmu.caps_attrs = intel_pmu_caps_attrs;
if (x86_pmu.lbr_nr) {
--
2.7.4
Powered by blists - more mailing lists