On Mon, Jun 30, 2014 at 04:50:52PM +0800, Yan, Zheng wrote: > LBR callstack is designed for PEBS, It does not work well with > FREEZE_LBRS_ON_PMI for non PEBS event. If FREEZE_LBRS_ON_PMI is set for > non PEBS event, PMIs near call/return instructions may cause superfluous > increase/decrease of LBR_TOS. > > This patch modifies __intel_pmu_lbr_enable() to not enable > FREEZE_LBRS_ON_PMI when LBR operates in callstack mode. We currently > don't use LBR callstack to capture kernel space callchain, so disabling > FREEZE_LBRS_ON_PMI should not be a problem. > > Signed-off-by: Yan, Zheng <zheng.z....@intel.com> > --- > arch/x86/kernel/cpu/perf_event_intel_lbr.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c > b/arch/x86/kernel/cpu/perf_event_intel_lbr.c > index f059b98..dd14f67 100644 > --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c > +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c > @@ -138,7 +138,14 @@ static void __intel_pmu_lbr_enable(void) > wrmsrl(MSR_LBR_SELECT, cpuc->lbr_sel->config); > > rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); > - debugctl |= (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI); > + debugctl |= DEBUGCTLMSR_LBR; > + /* > + * LBR callstack does not work well with FREEZE_LBRS_ON_PMI. > + * If FREEZE_LBRS_ON_PMI is set, PMI near call/return instructions > + * may cause superfluous increase/decrease of LBR_TOS. > + */ > + if (!cpuc->lbr_sel || !(cpuc->lbr_sel->config & LBR_CALL_STACK)) > + debugctl |= DEBUGCTLMSR_FREEZE_LBRS_ON_PMI; > wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
Something like so perhaps? Its slightly bigger, but less messy. diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index 9dd2459a4c73..a55670529b9e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -132,14 +132,18 @@ static void intel_pmu_lbr_filter(struct cpu_hw_events *cpuc); static void __intel_pmu_lbr_enable(void) { - u64 debugctl; struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + u64 debugctl, lbr_select = 0; - if (cpuc->lbr_sel) - wrmsrl(MSR_LBR_SELECT, cpuc->lbr_sel->config); + if (cpuc->lbr_sel) { + lbr_select = cpuc->lbr_sel->config; + wrmsrl(MSR_LBR_SELECT, lbr_config); + } rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); - debugctl |= (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI); + debugctl |= DEBUGCTLMSR_LBR; + if (!(lbr_select & LBR_CALL_STACK)) + debugctl |= DEBUGCTLMSR_FREEZE_LBRS_ON_PMI; wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); }
pgpsG4DrCabXs.pgp
Description: PGP signature