perf/x86/intel: Disable FREEZE_LBRS_ON_PMI when LBR operates in callstack mode
authorYan, Zheng <zheng.z.yan@intel.com>
Wed, 5 Nov 2014 02:56:10 +0000 (21:56 -0500)
committerIngo Molnar <mingo@kernel.org>
Wed, 18 Feb 2015 16:16:13 +0000 (17:16 +0100)
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.yan@intel.com>
Signed-off-by: Kan Liang <kan.liang@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: eranian@google.com
Cc: jolsa@redhat.com
Link: http://lkml.kernel.org/r/1415156173-10035-15-git-send-email-kan.liang@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/kernel/cpu/perf_event_intel_lbr.c

index a8b3f236cf373868b6cb51175fdc4ccf29fc7d1b..92a44fdbc9d35b87fc3e6bc6c9873d412dcbf1d9 100644 (file)
@@ -131,14 +131,23 @@ 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 = this_cpu_ptr(&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_select);
+       }
 
        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 (!(lbr_select & LBR_CALL_STACK))
+               debugctl |= DEBUGCTLMSR_FREEZE_LBRS_ON_PMI;
        wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
 }