Skip to content

Commit 21d59e3

Browse files
sandip4nPeter Zijlstra
authored andcommitted
perf/x86/amd/core: Detect PerfMonV2 support
AMD Performance Monitoring Version 2 (PerfMonV2) introduces some new Core PMU features such as detection of the number of available PMCs and managing PMCs using global registers namely, PerfCntrGlobalCtl and PerfCntrGlobalStatus. Clearing PerfCntrGlobalCtl and PerfCntrGlobalStatus ensures that all PMCs are inactive and have no pending overflows when CPUs are onlined or offlined. The PMU version (x86_pmu.version) now indicates PerfMonV2 support and will be used to bypass the new features on unsupported processors. Signed-off-by: Sandipan Das <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/dc8672ecbddff394e088ca8abf94b089b8ecc2e7.1650515382.git.sandipan.das@amd.com
1 parent 089be16 commit 21d59e3

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

arch/x86/events/amd/core.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ static unsigned long perf_nmi_window;
1919
#define AMD_MERGE_EVENT ((0xFULL << 32) | 0xFFULL)
2020
#define AMD_MERGE_EVENT_ENABLE (AMD_MERGE_EVENT | ARCH_PERFMON_EVENTSEL_ENABLE)
2121

22+
/* PMC Enable and Overflow bits for PerfCntrGlobal* registers */
23+
static u64 amd_pmu_global_cntr_mask __read_mostly;
24+
2225
static __initconst const u64 amd_hw_cache_event_ids
2326
[PERF_COUNT_HW_CACHE_MAX]
2427
[PERF_COUNT_HW_CACHE_OP_MAX]
@@ -578,6 +581,18 @@ static struct amd_nb *amd_alloc_nb(int cpu)
578581
return nb;
579582
}
580583

584+
static void amd_pmu_cpu_reset(int cpu)
585+
{
586+
if (x86_pmu.version < 2)
587+
return;
588+
589+
/* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */
590+
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0);
591+
592+
/* Clear overflow bits i.e. PerfCntrGLobalStatus.PerfCntrOvfl */
593+
wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, amd_pmu_global_cntr_mask);
594+
}
595+
581596
static int amd_pmu_cpu_prepare(int cpu)
582597
{
583598
struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
@@ -625,6 +640,7 @@ static void amd_pmu_cpu_starting(int cpu)
625640
cpuc->amd_nb->refcnt++;
626641

627642
amd_brs_reset();
643+
amd_pmu_cpu_reset(cpu);
628644
}
629645

630646
static void amd_pmu_cpu_dead(int cpu)
@@ -644,6 +660,8 @@ static void amd_pmu_cpu_dead(int cpu)
644660

645661
cpuhw->amd_nb = NULL;
646662
}
663+
664+
amd_pmu_cpu_reset(cpu);
647665
}
648666

649667
/*
@@ -1185,6 +1203,15 @@ static int __init amd_core_pmu_init(void)
11851203
x86_pmu.eventsel = MSR_F15H_PERF_CTL;
11861204
x86_pmu.perfctr = MSR_F15H_PERF_CTR;
11871205
x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE;
1206+
1207+
/* Check for Performance Monitoring v2 support */
1208+
if (boot_cpu_has(X86_FEATURE_PERFMON_V2)) {
1209+
/* Update PMU version for later usage */
1210+
x86_pmu.version = 2;
1211+
1212+
amd_pmu_global_cntr_mask = (1ULL << x86_pmu.num_counters) - 1;
1213+
}
1214+
11881215
/*
11891216
* AMD Core perfctr has separate MSRs for the NB events, see
11901217
* the amd/uncore.c driver.

0 commit comments

Comments
 (0)