Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf/x86/amd/lbr: Use freeze based on availability

Currently, the LBR code assumes that LBR Freeze is supported on all processors
when X86_FEATURE_AMD_LBR_V2 is available i.e. CPUID leaf 0x80000022[EAX]
bit 1 is set. This is incorrect as the availability of the feature is
additionally dependent on CPUID leaf 0x80000022[EAX] bit 2 being set,
which may not be set for all Zen 4 processors.

Define a new feature bit for LBR and PMC freeze and set the freeze enable bit
(FLBRI) in DebugCtl (MSR 0x1d9) conditionally.

It should still be possible to use LBR without freeze for profile-guided
optimization of user programs by using an user-only branch filter during
profiling. When the user-only filter is enabled, branches are no longer
recorded after the transition to CPL 0 upon PMI arrival. When branch
entries are read in the PMI handler, the branch stack does not change.

E.g.

$ perf record -j any,u -e ex_ret_brn_tkn ./workload

Since the feature bit is visible under flags in /proc/cpuinfo, it can be
used to determine the feasibility of use-cases which require LBR Freeze
to be supported by the hardware such as profile-guided optimization of
kernels.

Fixes: ca5b7c0d9621 ("perf/x86/amd/lbr: Add LbrExtV2 branch record support")
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/69a453c97cfd11c6f2584b19f937fe6df741510f.1711091584.git.sandipan.das@amd.com

authored by

Sandipan Das and committed by
Ingo Molnar
598c2faf 7f274e60

+21 -8
+2 -2
arch/x86/events/amd/core.c
··· 904 904 if (!status) 905 905 goto done; 906 906 907 - /* Read branch records before unfreezing */ 908 - if (status & GLOBAL_STATUS_LBRS_FROZEN) { 907 + /* Read branch records */ 908 + if (x86_pmu.lbr_nr) { 909 909 amd_pmu_lbr_read(); 910 910 status &= ~GLOBAL_STATUS_LBRS_FROZEN; 911 911 }
+10 -6
arch/x86/events/amd/lbr.c
··· 402 402 wrmsrl(MSR_AMD64_LBR_SELECT, lbr_select); 403 403 } 404 404 405 - rdmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl); 406 - rdmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg); 405 + if (cpu_feature_enabled(X86_FEATURE_AMD_LBR_PMC_FREEZE)) { 406 + rdmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl); 407 + wrmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI); 408 + } 407 409 408 - wrmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI); 410 + rdmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg); 409 411 wrmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg | DBG_EXTN_CFG_LBRV2EN); 410 412 } 411 413 ··· 420 418 return; 421 419 422 420 rdmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg); 423 - rdmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl); 424 - 425 421 wrmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg & ~DBG_EXTN_CFG_LBRV2EN); 426 - wrmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl & ~DEBUGCTLMSR_FREEZE_LBRS_ON_PMI); 422 + 423 + if (cpu_feature_enabled(X86_FEATURE_AMD_LBR_PMC_FREEZE)) { 424 + rdmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl); 425 + wrmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl & ~DEBUGCTLMSR_FREEZE_LBRS_ON_PMI); 426 + } 427 427 } 428 428 429 429 __init int amd_pmu_lbr_init(void)
+8
arch/x86/include/asm/cpufeatures.h
··· 460 460 #define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */ 461 461 462 462 /* 463 + * Extended auxiliary flags: Linux defined - for features scattered in various 464 + * CPUID levels like 0x80000022, etc. 465 + * 466 + * Reuse free bits when adding new feature flags! 467 + */ 468 + #define X86_FEATURE_AMD_LBR_PMC_FREEZE (21*32+ 0) /* AMD LBR and PMC Freeze */ 469 + 470 + /* 463 471 * BUG word(s) 464 472 */ 465 473 #define X86_BUG(x) (NCAPINTS*32 + (x))
+1
arch/x86/kernel/cpu/scattered.c
··· 49 49 { X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 }, 50 50 { X86_FEATURE_PERFMON_V2, CPUID_EAX, 0, 0x80000022, 0 }, 51 51 { X86_FEATURE_AMD_LBR_V2, CPUID_EAX, 1, 0x80000022, 0 }, 52 + { X86_FEATURE_AMD_LBR_PMC_FREEZE, CPUID_EAX, 2, 0x80000022, 0 }, 52 53 { 0, 0, 0, 0, 0 } 53 54 }; 54 55