Commit 703fb765 authored by Sandipan Das's avatar Sandipan Das Committed by Peter Zijlstra
Browse files

perf/x86/amd/lbr: Detect LbrExtV2 support



AMD Last Branch Record Extension Version 2 (LbrExtV2) is driven by Core PMC
overflows. It records recently taken branches up to the moment when the PMC
overflow occurs.

Detect the feature during PMU initialization and set the branch stack depth
using CPUID leaf 0x80000022 EBX.

Signed-off-by: default avatarSandipan Das <sandipan.das@amd.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/fc6e45378ada258f1bab79b0de6e05c393a8f1dd.1660211399.git.sandipan.das@amd.com
parent 257449c6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CPU_SUP_AMD)		+= core.o
obj-$(CONFIG_CPU_SUP_AMD)		+= core.o lbr.o
obj-$(CONFIG_PERF_EVENTS_AMD_BRS)	+= brs.o
obj-$(CONFIG_PERF_EVENTS_AMD_POWER)	+= power.o
obj-$(CONFIG_X86_LOCAL_APIC)		+= ibs.o
+5 −4
Original line number Diff line number Diff line
@@ -1374,10 +1374,11 @@ static int __init amd_core_pmu_init(void)
		x86_pmu.flags |= PMU_FL_PAIR;
	}

	/* LBR and BRS are mutually exclusive features */
	if (amd_pmu_lbr_init() && !amd_brs_init()) {
		/*
		 * BRS requires special event constraints and flushing on ctxsw.
		 */
	if (boot_cpu_data.x86 >= 0x19 && !amd_brs_init()) {
		x86_pmu.get_event_constraints = amd_get_event_constraints_f19h;
		x86_pmu.sched_task = amd_pmu_brs_sched_task;
		x86_pmu.limit_period = amd_pmu_limit_period;
+21 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#include <linux/perf_event.h>
#include <asm/perf_event.h>

#include "../perf_event.h"

__init int amd_pmu_lbr_init(void)
{
	union cpuid_0x80000022_ebx ebx;

	if (x86_pmu.version < 2 || !boot_cpu_has(X86_FEATURE_AMD_LBR_V2))
		return -EOPNOTSUPP;

	/* Set number of entries */
	ebx.full = cpuid_ebx(EXT_PERFMON_DEBUG_FEATURES);
	x86_pmu.lbr_nr = ebx.split.lbr_v2_stack_sz;

	pr_cont("%d-deep LBR, ", x86_pmu.lbr_nr);

	return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -1232,6 +1232,8 @@ static inline bool fixed_counter_disabled(int i, struct pmu *pmu)

int amd_pmu_init(void);

int amd_pmu_lbr_init(void);

#ifdef CONFIG_PERF_EVENTS_AMD_BRS

#define AMD_FAM19H_BRS_EVENT 0xc4 /* RETIRED_TAKEN_BRANCH_INSTRUCTIONS */
+2 −1
Original line number Diff line number Diff line
@@ -207,7 +207,8 @@ union cpuid_0x80000022_ebx {
	struct {
		/* Number of Core Performance Counters */
		unsigned int	num_core_pmc:4;
		unsigned int	reserved:6;
		/* Number of available LBR Stack Entries */
		unsigned int	lbr_v2_stack_sz:6;
		/* Number of Data Fabric Counters */
		unsigned int	num_df_pmc:6;
	} split;