Cleanup for Intel PMU initialization
Subsystems (3)
cover Cleanup for Intel PMU initialization
From: Kan Liang <[email protected]>
The patches are to clean up different features. They all touch the initialization code. There are some dependencies. So I put them in a patch set to facilitate the review and merge.
Patch 1 is to clear up the PEBS-via-PT on hybrid.
The original V1 patch can be found at
https://lore.kernel.org/lkml/[email protected]/
This is the V2, which only update the comments.
Patch 2 is to clean up the 023H enumeration.
To close the discussion at
https://lore.kernel.org/lkml/[email protected]/
Patch 3 is to clean up the counter information update and check codes. To close the discussion at
https://lore.kernel.org/lkml/[email protected]/
Kan Liang (3):
perf/x86/intel: Clean up PEBS-via-PT on hybrid perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF perf/x86/intel: Clean up counter information update and check
arch/x86/events/core.c | 10 +-- arch/x86/events/intel/core.c | 134 +++++++++++++++--------------- arch/x86/events/intel/ds.c | 10 ++- arch/x86/events/perf_event.h | 1 + arch/x86/include/asm/perf_event.h | 28 ++++++- 5 files changed, 106 insertions(+), 77 deletions(-)
Signature · 1 line
2.38.1
PATCH 1/3 perf/x86/intel: Clean up PEBS-via-PT on hybrid
From: Kan Liang <[email protected]>
The PEBS-via-PT feature is exposed for the e-core of some hybrid platforms, e.g., ADL and MTL. But it never works.
$ dmesg | grep PEBS [ 1.793888] core: cpu_atom PMU driver: PEBS-via-PT
$ perf record -c 1000 -e '{intel_pt/branch=0/,
cpu_atom/cpu-cycles,aux-output/pp}' -C8
Error:
The sys_perf_event_open() syscall returned with 22 (Invalid argument)
for event (cpu_atom/cpu-cycles,aux-output/pp).
"dmesg | grep -i perf" may provide additional information.The "PEBS-via-PT" is printed if the corresponding bit of per-PMU capabilities is set. Since the feature is supported by the e-core HW, perf sets the bit for e-core. However, for Intel PT, if a feature is not supported on all CPUs, it is not supported at all. The PEBS-via-PT event cannot be created successfully.
The PEBS-via-PT is no longer enumerated on the latest hybrid platform. It will be deprecated on future platforms with Arch PEBS. Let's remove it from the existing hybrid platforms.
---
The original V1 patch can be found at
https://lore.kernel.org/lkml/[email protected]/
The patch only updates the comments.
arch/x86/events/intel/core.c | 10 ---------- arch/x86/events/intel/ds.c | 10 +++++++++- 2 files changed, 9 insertions(+), 11 deletions(-)
arch/x86/events/intel/core.c +0 -10
@@ -4981,11 +4981,6 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)else pmu->intel_ctrl &= ~(1ULL <<GLOBAL_CTRL_EN_PERF_METRICS ); -if (pmu->intel_cap.pebs_output_pt_available) - pmu->pmu.capabilities |=PERF_PMU_CAP_AUX_OUTPUT ; -else - pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT ; - intel_pmu_check_event_constraints(pmu->event_constraints, pmu->cntr_mask64, pmu->fixed_cntr_mask64,
@@ -5063,9 +5058,6 @@ static bool init_hybrid_pmu(int cpu)pr_info ("%s PMU driver: " , pmu->name); -if (pmu->intel_cap.pebs_output_pt_available) -pr_cont ("PEBS-via-PT " ); -pr_cont ("\n" );x86_pmu_show_pmu_cap (&pmu->pmu);
@@ -6420,11 +6412,9 @@ static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus) pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;if (pmu->pmu_type & hybrid_small_tiny) { pmu->intel_cap.perf_metrics =0 ; - pmu->intel_cap.pebs_output_pt_available =1 ; pmu->mid_ack = true; }else if (pmu->pmu_type & hybrid_big) { pmu->intel_cap.perf_metrics =1 ; - pmu->intel_cap.pebs_output_pt_available =0 ; pmu->late_ack = true; } }
arch/x86/events/intel/ds.c +9 -1
@@ -2742,7 +2742,15 @@ void __init intel_ds_init(void) }pr_cont ("PEBS fmt%d%c%s, " , format, pebs_type, pebs_qual); -if (!is_hybrid () && x86_pmu.intel_cap.pebs_output_pt_available) { +/* +* The PEBS-via-PT is not supported on hybrid platforms, +* because not all CPUs of a hybrid machine support it. +* The global x86_pmu.intel_cap, which only contains the +* common capabilities, is used to check the availability +* of the feature. The per-PMU pebs_output_pt_available +* in a hybrid machine should be ignored. +*/ +if (x86_pmu.intel_cap.pebs_output_pt_available) {pr_cont ("PEBS-via-PT, " );x86_get_pmu (smp_processor_id ())->capabilities |=PERF_PMU_CAP_AUX_OUTPUT ; }
Signature · 1 line
2.38.1
[tip: perf/urgent] perf/x86/intel: Clean up PEBS-via-PT on hybrid
The following commit has been merged into the perf/urgent branch of tip:
The following commit has been merged into the perf/urgent branch of tip:
Commit-ID: 0a5561501397e2bbd0fb0e300eb489f72a90597a Gitweb: https://git.kernel.org/tip/0a5561501397e2bbd0fb0e300eb489f72a90597a Author: Kan Liang <[email protected]> AuthorDate: Wed, 29 Jan 2025 07:48:18 -08:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Sat, 08 Feb 2025 15:47:25 +01:00
perf/x86/intel: Clean up PEBS-via-PT on hybrid
The PEBS-via-PT feature is exposed for the e-core of some hybrid platforms, e.g., ADL and MTL. But it never works.
$ dmesg | grep PEBS [ 1.793888] core: cpu_atom PMU driver: PEBS-via-PT
$ perf record -c 1000 -e '{intel_pt/branch=0/,
cpu_atom/cpu-cycles,aux-output/pp}' -C8
Error:
The sys_perf_event_open() syscall returned with 22 (Invalid argument)
for event (cpu_atom/cpu-cycles,aux-output/pp).
"dmesg | grep -i perf" may provide additional information.The "PEBS-via-PT" is printed if the corresponding bit of per-PMU capabilities is set. Since the feature is supported by the e-core HW, perf sets the bit for e-core. However, for Intel PT, if a feature is not supported on all CPUs, it is not supported at all. The PEBS-via-PT event cannot be created successfully.
The PEBS-via-PT is no longer enumerated on the latest hybrid platform. It will be deprecated on future platforms with Arch PEBS. Let's remove it from the existing hybrid platforms.
--- arch/x86/events/intel/core.c | 10 ---------- arch/x86/events/intel/ds.c | 10 +++++++++- 2 files changed, 9 insertions(+), 11 deletions(-)
arch/x86/events/intel/core.c +0 -10
@@ -4941,11 +4941,6 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)else pmu->intel_ctrl &= ~(1ULL <<GLOBAL_CTRL_EN_PERF_METRICS ); -if (pmu->intel_cap.pebs_output_pt_available) - pmu->pmu.capabilities |=PERF_PMU_CAP_AUX_OUTPUT ; -else - pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT ; - intel_pmu_check_event_constraints(pmu->event_constraints, pmu->cntr_mask64, pmu->fixed_cntr_mask64,
@@ -5023,9 +5018,6 @@ static bool init_hybrid_pmu(int cpu)pr_info ("%s PMU driver: " , pmu->name); -if (pmu->intel_cap.pebs_output_pt_available) -pr_cont ("PEBS-via-PT " ); -pr_cont ("\n" );x86_pmu_show_pmu_cap (&pmu->pmu);
@@ -6370,11 +6362,9 @@ static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus) pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;if (pmu->pmu_type & hybrid_small_tiny) { pmu->intel_cap.perf_metrics =0 ; - pmu->intel_cap.pebs_output_pt_available =1 ; pmu->mid_ack = true; }else if (pmu->pmu_type & hybrid_big) { pmu->intel_cap.perf_metrics =1 ; - pmu->intel_cap.pebs_output_pt_available =0 ; pmu->late_ack = true; } }
arch/x86/events/intel/ds.c +9 -1
@@ -2578,7 +2578,15 @@ void __init intel_ds_init(void) }pr_cont ("PEBS fmt4%c%s, " , pebs_type, pebs_qual); -if (!is_hybrid () && x86_pmu.intel_cap.pebs_output_pt_available) { +/* +* The PEBS-via-PT is not supported on hybrid platforms, +* because not all CPUs of a hybrid machine support it. +* The global x86_pmu.intel_cap, which only contains the +* common capabilities, is used to check the availability +* of the feature. The per-PMU pebs_output_pt_available +* in a hybrid machine should be ignored. +*/ +if (x86_pmu.intel_cap.pebs_output_pt_available) {pr_cont ("PEBS-via-PT, " );x86_get_pmu (smp_processor_id ())->capabilities |=PERF_PMU_CAP_AUX_OUTPUT ; }
PATCH 2/3 perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF
In reply to [email protected]From: Kan Liang <[email protected]>
The EAX of the CPUID Leaf 023H enumerates the mask of valid sub-leaves. To tell the availability of the sub-leaf 1 (enumerate the counter mask), perf should check the bit 1 (0x2) of EAS, rather than bit 0 (0x1).
The error is not user-visible on bare metal. Because the sub-leaf 0 and the sub-leaf 1 are always available. However, it may bring issues in a virtualization environment when a VMM only enumerates the sub-leaf 0.
Introduce the cpuid35_e?x to replace the macros, which makes the implementation style consistent.
--- arch/x86/events/intel/core.c | 18 ++++++++++-------- arch/x86/include/asm/perf_event.h | 28 +++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 11 deletions(-)
arch/x86/events/intel/core.c +10 -8
@@ -4945,20 +4945,22 @@ static inline bool intel_pmu_broken_perf_cap(void)static void update_pmu_cap (struct x86_hybrid_pmu *pmu) { -unsigned int sub_bitmaps, eax, ebx, ecx, edx; +unsigned int cntr, fixed_cntr, ecx, edx; +union cpuid35_eax eax; +union cpuid35_ebx ebx; -cpuid (ARCH_PERFMON_EXT_LEAF , &sub_bitmaps, &ebx, &ecx, &edx); +cpuid (ARCH_PERFMON_EXT_LEAF , &eax.full, &ebx.full, &ecx, &edx); -if (ebx &ARCH_PERFMON_EXT_UMASK2 ) +if (ebx.split.umask2) pmu->config_mask |=ARCH_PERFMON_EVENTSEL_UMASK2 ; -if (ebx &ARCH_PERFMON_EXT_EQ ) +if (ebx.split.eq) pmu->config_mask |=ARCH_PERFMON_EVENTSEL_EQ ; -if (sub_bitmaps &ARCH_PERFMON_NUM_COUNTER_LEAF_BIT ) { +if (eax.split.cntr_subleaf) {cpuid_count (ARCH_PERFMON_EXT_LEAF ,ARCH_PERFMON_NUM_COUNTER_LEAF , - &eax, &ebx, &ecx, &edx); - pmu->cntr_mask64 = eax; - pmu->fixed_cntr_mask64 = ebx; + &cntr, &fixed_cntr, &ecx, &edx); + pmu->cntr_mask64 = cntr; + pmu->fixed_cntr_mask64 = fixed_cntr; }if (!intel_pmu_broken_perf_cap ()) {
arch/x86/include/asm/perf_event.h +25 -3
@@ -194,11 +194,33 @@ union cpuid10_edx {* detection/enumeration details: */ #define ARCH_PERFMON_EXT_LEAF 0x00000023 -#define ARCH_PERFMON_EXT_UMASK2 0x1 -#define ARCH_PERFMON_EXT_EQ 0x2 -#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT 0x1#define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1 +union cpuid35_eax { +struct { +unsigned int leaf0:1 ; +/* Counters Sub-Leaf */ +unsigned int cntr_subleaf:1 ; +/* Auto Counter Reload Sub-Leaf */ +unsigned int acr_subleaf:1 ; +/* Events Sub-Leaf */ +unsigned int events_subleaf:1 ; +unsigned int reserved:28 ; + } split; +unsigned int full; +}; + +union cpuid35_ebx { +struct { +/* UnitMask2 Supported */ +unsigned int umask2:1 ; +/* EQ-bit Supported */ +unsigned int eq:1 ; +unsigned int reserved:30 ; + } split; +unsigned int full; +}; +/* * Intel Architectural LBR CPUID detection/enumeration details: */
Signature · 1 line
2.38.1
[tip: perf/urgent] perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF
The following commit has been merged into the perf/urgent branch of tip:
The following commit has been merged into the perf/urgent branch of tip:
Commit-ID: 47a973fd75639fe80d59f9e1860113bb2a0b112b Gitweb: https://git.kernel.org/tip/47a973fd75639fe80d59f9e1860113bb2a0b112b Author: Kan Liang <[email protected]> AuthorDate: Wed, 29 Jan 2025 07:48:19 -08:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Sat, 08 Feb 2025 15:47:25 +01:00
perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF
The EAX of the CPUID Leaf 023H enumerates the mask of valid sub-leaves. To tell the availability of the sub-leaf 1 (enumerate the counter mask), perf should check the bit 1 (0x2) of EAS, rather than bit 0 (0x1).
The error is not user-visible on bare metal. Because the sub-leaf 0 and the sub-leaf 1 are always available. However, it may bring issues in a virtualization environment when a VMM only enumerates the sub-leaf 0.
Introduce the cpuid35_e?x to replace the macros, which makes the implementation style consistent.
--- arch/x86/events/intel/core.c | 18 ++++++++++-------- arch/x86/include/asm/perf_event.h | 28 +++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 11 deletions(-)
arch/x86/events/intel/core.c +10 -8
@@ -4905,20 +4905,22 @@ static inline bool intel_pmu_broken_perf_cap(void)static void update_pmu_cap (struct x86_hybrid_pmu *pmu) { -unsigned int sub_bitmaps, eax, ebx, ecx, edx; +unsigned int cntr, fixed_cntr, ecx, edx; +union cpuid35_eax eax; +union cpuid35_ebx ebx; -cpuid (ARCH_PERFMON_EXT_LEAF , &sub_bitmaps, &ebx, &ecx, &edx); +cpuid (ARCH_PERFMON_EXT_LEAF , &eax.full, &ebx.full, &ecx, &edx); -if (ebx &ARCH_PERFMON_EXT_UMASK2 ) +if (ebx.split.umask2) pmu->config_mask |=ARCH_PERFMON_EVENTSEL_UMASK2 ; -if (ebx &ARCH_PERFMON_EXT_EQ ) +if (ebx.split.eq) pmu->config_mask |=ARCH_PERFMON_EVENTSEL_EQ ; -if (sub_bitmaps &ARCH_PERFMON_NUM_COUNTER_LEAF_BIT ) { +if (eax.split.cntr_subleaf) {cpuid_count (ARCH_PERFMON_EXT_LEAF ,ARCH_PERFMON_NUM_COUNTER_LEAF , - &eax, &ebx, &ecx, &edx); - pmu->cntr_mask64 = eax; - pmu->fixed_cntr_mask64 = ebx; + &cntr, &fixed_cntr, &ecx, &edx); + pmu->cntr_mask64 = cntr; + pmu->fixed_cntr_mask64 = fixed_cntr; }if (!intel_pmu_broken_perf_cap ()) {
arch/x86/include/asm/perf_event.h +25 -3
@@ -188,11 +188,33 @@ union cpuid10_edx {* detection/enumeration details: */ #define ARCH_PERFMON_EXT_LEAF 0x00000023 -#define ARCH_PERFMON_EXT_UMASK2 0x1 -#define ARCH_PERFMON_EXT_EQ 0x2 -#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT 0x1#define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1 +union cpuid35_eax { +struct { +unsigned int leaf0:1 ; +/* Counters Sub-Leaf */ +unsigned int cntr_subleaf:1 ; +/* Auto Counter Reload Sub-Leaf */ +unsigned int acr_subleaf:1 ; +/* Events Sub-Leaf */ +unsigned int events_subleaf:1 ; +unsigned int reserved:28 ; + } split; +unsigned int full; +}; + +union cpuid35_ebx { +struct { +/* UnitMask2 Supported */ +unsigned int umask2:1 ; +/* EQ-bit Supported */ +unsigned int eq:1 ; +unsigned int reserved:30 ; + } split; +unsigned int full; +}; +/* * Intel Architectural LBR CPUID detection/enumeration details: */
PATCH 3/3 perf/x86/intel: Clean up counter information update and check
In reply to [email protected]From: Kan Liang <[email protected]>
The counter-related PMU information may be updated in different places on different platforms. For hybrid machines, the accurate counter information can only be retrieved when the specific CPU is online. The information is updated in intel_pmu_cpu_starting()->init_hybrid_pmu().
For non-hybrid machines, the information is initialized in the intel_pmu_init() when booting CPU0.
The counter information doesn't impact the PMU registration and should not necessarily be in intel_pmu_init().
Setup/update the counter-related PMU information in the CPU starting stage for all Intel platforms. The x86_pmu_show_pmu_cap() has to be delayed until all the information is updated. Add a PMU_FL_LATE_SETUP flag to indicate the late setup/update case.
--- arch/x86/events/core.c | 10 ++-- arch/x86/events/intel/core.c | 112 ++++++++++++++++++----------------- arch/x86/events/perf_event.h | 1 + 3 files changed, 65 insertions(+), 58 deletions(-)
arch/x86/events/core.c +5 -5
@@ -2119,10 +2119,6 @@ static int __init init_hw_perf_events(void)perf_events_lapic_init ();register_nmi_handler (NMI_LOCAL , perf_event_nmi_handler,0 ,"PMI" ); - unconstrained = (struct event_constraint ) -__EVENT_CONSTRAINT (0 , x86_pmu.cntr_mask64, -0 ,x86_pmu_num_counters (NULL ),0 ,0 ); - x86_pmu_format_group.attrs = x86_pmu.format_attrs;if (!x86_pmu.events_sysfs_show)
@@ -2130,8 +2126,12 @@ static int __init init_hw_perf_events(void) pmu.attr_update = x86_pmu.attr_update; -if (!is_hybrid ()) +if (!(x86_pmu.flags &PMU_FL_LATE_SETUP )) { + unconstrained = (struct event_constraint ) +__EVENT_CONSTRAINT (0 , x86_pmu.cntr_mask64, +0 ,x86_pmu_num_counters (NULL ),0 ,0 );x86_pmu_show_pmu_cap (NULL ); + }if (!x86_pmu.read) x86_pmu.read = _x86_pmu_read;
arch/x86/events/intel/core.c +59 -53
195 lines not on this page · raw message
arch/x86/events/perf_event.h +1 -0
@@ -1066,6 +1066,7 @@ do { \#define PMU_FL_MEM_LOADS_AUX 0x100/* Require an auxiliary event for the complete memory info */ #define PMU_FL_RETIRE_LATENCY 0x200/* Support Retire Latency in PEBS */ #define PMU_FL_BR_CNTR 0x400/* Support branch counter logging */ +#define PMU_FL_LATE_SETUP 0x800/* Setup/Update PMU info when CPU starts */ #define EVENT_VAR (_id) event_attr_##_id#define EVENT_PTR (_id) &event_attr_##_id.attr.attr
Signature · 1 line
2.38.1
Peter Zijlstra
maintainerQuoted 11 lines · On Wed, Jan 29, 2025 at 07:48:17AM -0800, [email protected] wrote:
From: Kan Liang <[email protected]>
The patches are to clean up different features. They all touch the initialization code. There are some dependencies. So I put them in a patch set to facilitate the review and merge.
Patch 1 is to clear up the PEBS-via-PT on hybrid.
The original V1 patch can be found at
https://lore.kernel.org/lkml/[email protected]/
This is the V2, which only update the comments.
Quoted 7 lines
Patch 2 is to clean up the 023H enumeration.
To close the discussion at
https://lore.kernel.org/lkml/[email protected]/Patch 3 is to clean up the counter information update and check codes. To close the discussion at
https://lore.kernel.org/lkml/[email protected]/
So I can take 1 and 2, but 3 is part of that arch pebs things, and that series is not in a shape I want to apply.
Also, I'm not at all sure 3 improves things, it might just make it worse.
Quoted 16 lines · Peter Zijlstra
Quoted 15 lines · On Wed, Jan 29, 2025 at 07:48:17AM -0800, [email protected] wrote:
From: Kan Liang <[email protected]>
The patches are to clean up different features. They all touch the initialization code. There are some dependencies. So I put them in a patch set to facilitate the review and merge.
Patch 1 is to clear up the PEBS-via-PT on hybrid.
The original V1 patch can be found at
https://lore.kernel.org/lkml/[email protected]/
This is the V2, which only update the comments.Patch 2 is to clean up the 023H enumeration.
To close the discussion at
https://lore.kernel.org/lkml/[email protected]/
Quoted 5 lines
Quoted 3 lines
Patch 3 is to clean up the counter information update and check codes. To close the discussion at
https://lore.kernel.org/lkml/[email protected]/So I can take 1 and 2,
Thanks.
Quoted 5 lines
but 3 is part of that arch pebs things, and that
series is not in a shape I want to apply.Also, I'm not at all sure 3 improves things, it might just make it worse.
There should be some improvements for the initialization code. At least, we can reduce the is_hybrid() check and move the 0x23 enumeration in one place.
Anyway, I will think more and see if there is more that can be improved. Then, put it as part of the arch pebs code. We may have further discussions with the V2 arch PEBS code.
Thanks,
Kan