* [PATCH V2 01/13] perf/x86/intel/uncore: Move uncore discovery init struct to header
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 1:47 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 02/13] perf/x86/intel/uncore: Support per-platform discovery base devices Zide Chen
` (12 subsequent siblings)
13 siblings, 2 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
The discovery base MSR or PCI device is platform-specific and must be
defined statically in the per-platform init table and passed to the
discovery code.
Move the definition of struct intel_uncore_init_fun to uncore.h so it
can be accessed by discovery code, and rename it to reflect that it
now carries more than just init callbacks.
Shorten intel_uncore_has_discovery_tables[_pci/msr] to
uncore_discovery[_pci/msr] for improved readability and alignment.
Drop the `intel_` prefix from new names since the code is under the
intel directory and long identifiers make alignment harder. Further
cleanups will continue removing `intel_` prefixes.
No functional change intended.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2: New patch
arch/x86/events/intel/uncore.c | 72 ++++++++++--------------
arch/x86/events/intel/uncore.h | 10 ++++
arch/x86/events/intel/uncore_discovery.c | 12 ++--
arch/x86/events/intel/uncore_discovery.h | 2 +-
4 files changed, 49 insertions(+), 47 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index e228e564b15e..cd561290be8c 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1697,133 +1697,123 @@ static int __init uncore_mmio_init(void)
return ret;
}
-struct intel_uncore_init_fun {
- void (*cpu_init)(void);
- int (*pci_init)(void);
- void (*mmio_init)(void);
- /* Discovery table is required */
- bool use_discovery;
- /* The units in the discovery table should be ignored. */
- int *uncore_units_ignore;
-};
-
-static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
+static const struct uncore_plat_init nhm_uncore_init __initconst = {
.cpu_init = nhm_uncore_cpu_init,
};
-static const struct intel_uncore_init_fun snb_uncore_init __initconst = {
+static const struct uncore_plat_init snb_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = snb_uncore_pci_init,
};
-static const struct intel_uncore_init_fun ivb_uncore_init __initconst = {
+static const struct uncore_plat_init ivb_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = ivb_uncore_pci_init,
};
-static const struct intel_uncore_init_fun hsw_uncore_init __initconst = {
+static const struct uncore_plat_init hsw_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = hsw_uncore_pci_init,
};
-static const struct intel_uncore_init_fun bdw_uncore_init __initconst = {
+static const struct uncore_plat_init bdw_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = bdw_uncore_pci_init,
};
-static const struct intel_uncore_init_fun snbep_uncore_init __initconst = {
+static const struct uncore_plat_init snbep_uncore_init __initconst = {
.cpu_init = snbep_uncore_cpu_init,
.pci_init = snbep_uncore_pci_init,
};
-static const struct intel_uncore_init_fun nhmex_uncore_init __initconst = {
+static const struct uncore_plat_init nhmex_uncore_init __initconst = {
.cpu_init = nhmex_uncore_cpu_init,
};
-static const struct intel_uncore_init_fun ivbep_uncore_init __initconst = {
+static const struct uncore_plat_init ivbep_uncore_init __initconst = {
.cpu_init = ivbep_uncore_cpu_init,
.pci_init = ivbep_uncore_pci_init,
};
-static const struct intel_uncore_init_fun hswep_uncore_init __initconst = {
+static const struct uncore_plat_init hswep_uncore_init __initconst = {
.cpu_init = hswep_uncore_cpu_init,
.pci_init = hswep_uncore_pci_init,
};
-static const struct intel_uncore_init_fun bdx_uncore_init __initconst = {
+static const struct uncore_plat_init bdx_uncore_init __initconst = {
.cpu_init = bdx_uncore_cpu_init,
.pci_init = bdx_uncore_pci_init,
};
-static const struct intel_uncore_init_fun knl_uncore_init __initconst = {
+static const struct uncore_plat_init knl_uncore_init __initconst = {
.cpu_init = knl_uncore_cpu_init,
.pci_init = knl_uncore_pci_init,
};
-static const struct intel_uncore_init_fun skl_uncore_init __initconst = {
+static const struct uncore_plat_init skl_uncore_init __initconst = {
.cpu_init = skl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};
-static const struct intel_uncore_init_fun skx_uncore_init __initconst = {
+static const struct uncore_plat_init skx_uncore_init __initconst = {
.cpu_init = skx_uncore_cpu_init,
.pci_init = skx_uncore_pci_init,
};
-static const struct intel_uncore_init_fun icl_uncore_init __initconst = {
+static const struct uncore_plat_init icl_uncore_init __initconst = {
.cpu_init = icl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};
-static const struct intel_uncore_init_fun tgl_uncore_init __initconst = {
+static const struct uncore_plat_init tgl_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.mmio_init = tgl_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun tgl_l_uncore_init __initconst = {
+static const struct uncore_plat_init tgl_l_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.mmio_init = tgl_l_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun rkl_uncore_init __initconst = {
+static const struct uncore_plat_init rkl_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};
-static const struct intel_uncore_init_fun adl_uncore_init __initconst = {
+static const struct uncore_plat_init adl_uncore_init __initconst = {
.cpu_init = adl_uncore_cpu_init,
.mmio_init = adl_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun mtl_uncore_init __initconst = {
+static const struct uncore_plat_init mtl_uncore_init __initconst = {
.cpu_init = mtl_uncore_cpu_init,
.mmio_init = adl_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun lnl_uncore_init __initconst = {
+static const struct uncore_plat_init lnl_uncore_init __initconst = {
.cpu_init = lnl_uncore_cpu_init,
.mmio_init = lnl_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun ptl_uncore_init __initconst = {
+static const struct uncore_plat_init ptl_uncore_init __initconst = {
.cpu_init = ptl_uncore_cpu_init,
.mmio_init = ptl_uncore_mmio_init,
.use_discovery = true,
};
-static const struct intel_uncore_init_fun icx_uncore_init __initconst = {
+static const struct uncore_plat_init icx_uncore_init __initconst = {
.cpu_init = icx_uncore_cpu_init,
.pci_init = icx_uncore_pci_init,
.mmio_init = icx_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun snr_uncore_init __initconst = {
+static const struct uncore_plat_init snr_uncore_init __initconst = {
.cpu_init = snr_uncore_cpu_init,
.pci_init = snr_uncore_pci_init,
.mmio_init = snr_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
+static const struct uncore_plat_init spr_uncore_init __initconst = {
.cpu_init = spr_uncore_cpu_init,
.pci_init = spr_uncore_pci_init,
.mmio_init = spr_uncore_mmio_init,
@@ -1831,7 +1821,7 @@ static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
.uncore_units_ignore = spr_uncore_units_ignore,
};
-static const struct intel_uncore_init_fun gnr_uncore_init __initconst = {
+static const struct uncore_plat_init gnr_uncore_init __initconst = {
.cpu_init = gnr_uncore_cpu_init,
.pci_init = gnr_uncore_pci_init,
.mmio_init = gnr_uncore_mmio_init,
@@ -1839,7 +1829,7 @@ static const struct intel_uncore_init_fun gnr_uncore_init __initconst = {
.uncore_units_ignore = gnr_uncore_units_ignore,
};
-static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
+static const struct uncore_plat_init generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
.mmio_init = intel_uncore_generic_uncore_mmio_init,
@@ -1910,7 +1900,7 @@ MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
static int __init intel_uncore_init(void)
{
const struct x86_cpu_id *id;
- struct intel_uncore_init_fun *uncore_init;
+ struct uncore_plat_init *uncore_init;
int pret = 0, cret = 0, mret = 0, ret;
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
@@ -1921,16 +1911,16 @@ static int __init intel_uncore_init(void)
id = x86_match_cpu(intel_uncore_match);
if (!id) {
- if (!uncore_no_discover && intel_uncore_has_discovery_tables(NULL))
- uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
+ if (!uncore_no_discover && uncore_discovery(NULL))
+ uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
else
return -ENODEV;
} else {
- uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
+ uncore_init = (struct uncore_plat_init *)id->driver_data;
if (uncore_no_discover && uncore_init->use_discovery)
return -ENODEV;
if (uncore_init->use_discovery &&
- !intel_uncore_has_discovery_tables(uncore_init->uncore_units_ignore))
+ !uncore_discovery(uncore_init))
return -ENODEV;
}
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index d8815fff7588..568536ef28ee 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -47,6 +47,16 @@ struct uncore_event_desc;
struct freerunning_counters;
struct intel_uncore_topology;
+struct uncore_plat_init {
+ void (*cpu_init)(void);
+ int (*pci_init)(void);
+ void (*mmio_init)(void);
+ /* Discovery table is required */
+ bool use_discovery;
+ /* The units in the discovery table should be ignored. */
+ int *uncore_units_ignore;
+};
+
struct intel_uncore_type {
const char *name;
int num_counters;
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 7d57ce706feb..d39f6a0b8cc3 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -350,7 +350,7 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
return __parse_discovery_table(addr, die, parsed, ignore);
}
-static bool intel_uncore_has_discovery_tables_pci(int *ignore)
+static bool uncore_discovery_pci(int *ignore)
{
u32 device, val, entry_id, bar_offset;
int die, dvsec = 0, ret = true;
@@ -399,7 +399,7 @@ static bool intel_uncore_has_discovery_tables_pci(int *ignore)
return ret;
}
-static bool intel_uncore_has_discovery_tables_msr(int *ignore)
+static bool uncore_discovery_msr(int *ignore)
{
unsigned long *die_mask;
bool parsed = false;
@@ -432,10 +432,12 @@ static bool intel_uncore_has_discovery_tables_msr(int *ignore)
return parsed;
}
-bool intel_uncore_has_discovery_tables(int *ignore)
+bool uncore_discovery(struct uncore_plat_init *init)
{
- return intel_uncore_has_discovery_tables_msr(ignore) ||
- intel_uncore_has_discovery_tables_pci(ignore);
+ int *ignore = init ? init->uncore_units_ignore : NULL;
+
+ return uncore_discovery_msr(ignore) ||
+ uncore_discovery_pci(ignore);
}
void intel_uncore_clear_discovery_tables(void)
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index dff75c98e22f..dfc237a2b6df 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -136,7 +136,7 @@ struct intel_uncore_discovery_type {
u16 num_units; /* number of units */
};
-bool intel_uncore_has_discovery_tables(int *ignore);
+bool uncore_discovery(struct uncore_plat_init *init);
void intel_uncore_clear_discovery_tables(void);
void intel_uncore_generic_uncore_cpu_init(void);
int intel_uncore_generic_uncore_pci_init(void);
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 01/13] perf/x86/intel/uncore: Move uncore discovery init struct to header
2025-12-31 22:42 ` [PATCH V2 01/13] perf/x86/intel/uncore: Move uncore discovery init struct to header Zide Chen
@ 2026-01-04 1:47 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 1:47 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> The discovery base MSR or PCI device is platform-specific and must be
> defined statically in the per-platform init table and passed to the
> discovery code.
>
> Move the definition of struct intel_uncore_init_fun to uncore.h so it
> can be accessed by discovery code, and rename it to reflect that it
> now carries more than just init callbacks.
>
> Shorten intel_uncore_has_discovery_tables[_pci/msr] to
> uncore_discovery[_pci/msr] for improved readability and alignment.
>
> Drop the `intel_` prefix from new names since the code is under the
> intel directory and long identifiers make alignment harder. Further
> cleanups will continue removing `intel_` prefixes.
>
> No functional change intended.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2: New patch
>
> arch/x86/events/intel/uncore.c | 72 ++++++++++--------------
> arch/x86/events/intel/uncore.h | 10 ++++
> arch/x86/events/intel/uncore_discovery.c | 12 ++--
> arch/x86/events/intel/uncore_discovery.h | 2 +-
> 4 files changed, 49 insertions(+), 47 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index e228e564b15e..cd561290be8c 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -1697,133 +1697,123 @@ static int __init uncore_mmio_init(void)
> return ret;
> }
>
> -struct intel_uncore_init_fun {
> - void (*cpu_init)(void);
> - int (*pci_init)(void);
> - void (*mmio_init)(void);
> - /* Discovery table is required */
> - bool use_discovery;
> - /* The units in the discovery table should be ignored. */
> - int *uncore_units_ignore;
> -};
> -
> -static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
> +static const struct uncore_plat_init nhm_uncore_init __initconst = {
> .cpu_init = nhm_uncore_cpu_init,
> };
>
> -static const struct intel_uncore_init_fun snb_uncore_init __initconst = {
> +static const struct uncore_plat_init snb_uncore_init __initconst = {
> .cpu_init = snb_uncore_cpu_init,
> .pci_init = snb_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun ivb_uncore_init __initconst = {
> +static const struct uncore_plat_init ivb_uncore_init __initconst = {
> .cpu_init = snb_uncore_cpu_init,
> .pci_init = ivb_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun hsw_uncore_init __initconst = {
> +static const struct uncore_plat_init hsw_uncore_init __initconst = {
> .cpu_init = snb_uncore_cpu_init,
> .pci_init = hsw_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun bdw_uncore_init __initconst = {
> +static const struct uncore_plat_init bdw_uncore_init __initconst = {
> .cpu_init = snb_uncore_cpu_init,
> .pci_init = bdw_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun snbep_uncore_init __initconst = {
> +static const struct uncore_plat_init snbep_uncore_init __initconst = {
> .cpu_init = snbep_uncore_cpu_init,
> .pci_init = snbep_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun nhmex_uncore_init __initconst = {
> +static const struct uncore_plat_init nhmex_uncore_init __initconst = {
> .cpu_init = nhmex_uncore_cpu_init,
> };
>
> -static const struct intel_uncore_init_fun ivbep_uncore_init __initconst = {
> +static const struct uncore_plat_init ivbep_uncore_init __initconst = {
> .cpu_init = ivbep_uncore_cpu_init,
> .pci_init = ivbep_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun hswep_uncore_init __initconst = {
> +static const struct uncore_plat_init hswep_uncore_init __initconst = {
> .cpu_init = hswep_uncore_cpu_init,
> .pci_init = hswep_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun bdx_uncore_init __initconst = {
> +static const struct uncore_plat_init bdx_uncore_init __initconst = {
> .cpu_init = bdx_uncore_cpu_init,
> .pci_init = bdx_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun knl_uncore_init __initconst = {
> +static const struct uncore_plat_init knl_uncore_init __initconst = {
> .cpu_init = knl_uncore_cpu_init,
> .pci_init = knl_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun skl_uncore_init __initconst = {
> +static const struct uncore_plat_init skl_uncore_init __initconst = {
> .cpu_init = skl_uncore_cpu_init,
> .pci_init = skl_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun skx_uncore_init __initconst = {
> +static const struct uncore_plat_init skx_uncore_init __initconst = {
> .cpu_init = skx_uncore_cpu_init,
> .pci_init = skx_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun icl_uncore_init __initconst = {
> +static const struct uncore_plat_init icl_uncore_init __initconst = {
> .cpu_init = icl_uncore_cpu_init,
> .pci_init = skl_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun tgl_uncore_init __initconst = {
> +static const struct uncore_plat_init tgl_uncore_init __initconst = {
> .cpu_init = tgl_uncore_cpu_init,
> .mmio_init = tgl_uncore_mmio_init,
> };
>
> -static const struct intel_uncore_init_fun tgl_l_uncore_init __initconst = {
> +static const struct uncore_plat_init tgl_l_uncore_init __initconst = {
> .cpu_init = tgl_uncore_cpu_init,
> .mmio_init = tgl_l_uncore_mmio_init,
> };
>
> -static const struct intel_uncore_init_fun rkl_uncore_init __initconst = {
> +static const struct uncore_plat_init rkl_uncore_init __initconst = {
> .cpu_init = tgl_uncore_cpu_init,
> .pci_init = skl_uncore_pci_init,
> };
>
> -static const struct intel_uncore_init_fun adl_uncore_init __initconst = {
> +static const struct uncore_plat_init adl_uncore_init __initconst = {
> .cpu_init = adl_uncore_cpu_init,
> .mmio_init = adl_uncore_mmio_init,
> };
>
> -static const struct intel_uncore_init_fun mtl_uncore_init __initconst = {
> +static const struct uncore_plat_init mtl_uncore_init __initconst = {
> .cpu_init = mtl_uncore_cpu_init,
> .mmio_init = adl_uncore_mmio_init,
> };
>
> -static const struct intel_uncore_init_fun lnl_uncore_init __initconst = {
> +static const struct uncore_plat_init lnl_uncore_init __initconst = {
> .cpu_init = lnl_uncore_cpu_init,
> .mmio_init = lnl_uncore_mmio_init,
> };
>
> -static const struct intel_uncore_init_fun ptl_uncore_init __initconst = {
> +static const struct uncore_plat_init ptl_uncore_init __initconst = {
> .cpu_init = ptl_uncore_cpu_init,
> .mmio_init = ptl_uncore_mmio_init,
> .use_discovery = true,
> };
>
> -static const struct intel_uncore_init_fun icx_uncore_init __initconst = {
> +static const struct uncore_plat_init icx_uncore_init __initconst = {
> .cpu_init = icx_uncore_cpu_init,
> .pci_init = icx_uncore_pci_init,
> .mmio_init = icx_uncore_mmio_init,
> };
>
> -static const struct intel_uncore_init_fun snr_uncore_init __initconst = {
> +static const struct uncore_plat_init snr_uncore_init __initconst = {
> .cpu_init = snr_uncore_cpu_init,
> .pci_init = snr_uncore_pci_init,
> .mmio_init = snr_uncore_mmio_init,
> };
>
> -static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
> +static const struct uncore_plat_init spr_uncore_init __initconst = {
> .cpu_init = spr_uncore_cpu_init,
> .pci_init = spr_uncore_pci_init,
> .mmio_init = spr_uncore_mmio_init,
> @@ -1831,7 +1821,7 @@ static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
> .uncore_units_ignore = spr_uncore_units_ignore,
> };
>
> -static const struct intel_uncore_init_fun gnr_uncore_init __initconst = {
> +static const struct uncore_plat_init gnr_uncore_init __initconst = {
> .cpu_init = gnr_uncore_cpu_init,
> .pci_init = gnr_uncore_pci_init,
> .mmio_init = gnr_uncore_mmio_init,
> @@ -1839,7 +1829,7 @@ static const struct intel_uncore_init_fun gnr_uncore_init __initconst = {
> .uncore_units_ignore = gnr_uncore_units_ignore,
> };
>
> -static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
> +static const struct uncore_plat_init generic_uncore_init __initconst = {
> .cpu_init = intel_uncore_generic_uncore_cpu_init,
> .pci_init = intel_uncore_generic_uncore_pci_init,
> .mmio_init = intel_uncore_generic_uncore_mmio_init,
> @@ -1910,7 +1900,7 @@ MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
> static int __init intel_uncore_init(void)
> {
> const struct x86_cpu_id *id;
> - struct intel_uncore_init_fun *uncore_init;
> + struct uncore_plat_init *uncore_init;
> int pret = 0, cret = 0, mret = 0, ret;
>
> if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
> @@ -1921,16 +1911,16 @@ static int __init intel_uncore_init(void)
>
> id = x86_match_cpu(intel_uncore_match);
> if (!id) {
> - if (!uncore_no_discover && intel_uncore_has_discovery_tables(NULL))
> - uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
> + if (!uncore_no_discover && uncore_discovery(NULL))
> + uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
> else
> return -ENODEV;
> } else {
> - uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
> + uncore_init = (struct uncore_plat_init *)id->driver_data;
> if (uncore_no_discover && uncore_init->use_discovery)
> return -ENODEV;
> if (uncore_init->use_discovery &&
> - !intel_uncore_has_discovery_tables(uncore_init->uncore_units_ignore))
> + !uncore_discovery(uncore_init))
> return -ENODEV;
> }
>
> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
> index d8815fff7588..568536ef28ee 100644
> --- a/arch/x86/events/intel/uncore.h
> +++ b/arch/x86/events/intel/uncore.h
> @@ -47,6 +47,16 @@ struct uncore_event_desc;
> struct freerunning_counters;
> struct intel_uncore_topology;
>
> +struct uncore_plat_init {
> + void (*cpu_init)(void);
> + int (*pci_init)(void);
> + void (*mmio_init)(void);
> + /* Discovery table is required */
> + bool use_discovery;
> + /* The units in the discovery table should be ignored. */
> + int *uncore_units_ignore;
> +};
> +
> struct intel_uncore_type {
> const char *name;
> int num_counters;
> diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
> index 7d57ce706feb..d39f6a0b8cc3 100644
> --- a/arch/x86/events/intel/uncore_discovery.c
> +++ b/arch/x86/events/intel/uncore_discovery.c
> @@ -350,7 +350,7 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
> return __parse_discovery_table(addr, die, parsed, ignore);
> }
>
> -static bool intel_uncore_has_discovery_tables_pci(int *ignore)
> +static bool uncore_discovery_pci(int *ignore)
> {
> u32 device, val, entry_id, bar_offset;
> int die, dvsec = 0, ret = true;
> @@ -399,7 +399,7 @@ static bool intel_uncore_has_discovery_tables_pci(int *ignore)
> return ret;
> }
>
> -static bool intel_uncore_has_discovery_tables_msr(int *ignore)
> +static bool uncore_discovery_msr(int *ignore)
> {
> unsigned long *die_mask;
> bool parsed = false;
> @@ -432,10 +432,12 @@ static bool intel_uncore_has_discovery_tables_msr(int *ignore)
> return parsed;
> }
>
> -bool intel_uncore_has_discovery_tables(int *ignore)
> +bool uncore_discovery(struct uncore_plat_init *init)
> {
> - return intel_uncore_has_discovery_tables_msr(ignore) ||
> - intel_uncore_has_discovery_tables_pci(ignore);
> + int *ignore = init ? init->uncore_units_ignore : NULL;
> +
> + return uncore_discovery_msr(ignore) ||
> + uncore_discovery_pci(ignore);
> }
>
> void intel_uncore_clear_discovery_tables(void)
> diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
> index dff75c98e22f..dfc237a2b6df 100644
> --- a/arch/x86/events/intel/uncore_discovery.h
> +++ b/arch/x86/events/intel/uncore_discovery.h
> @@ -136,7 +136,7 @@ struct intel_uncore_discovery_type {
> u16 num_units; /* number of units */
> };
>
> -bool intel_uncore_has_discovery_tables(int *ignore);
> +bool uncore_discovery(struct uncore_plat_init *init);
> void intel_uncore_clear_discovery_tables(void);
> void intel_uncore_generic_uncore_cpu_init(void);
> int intel_uncore_generic_uncore_pci_init(void);
LGTM.
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Move uncore discovery init struct to header
2025-12-31 22:42 ` [PATCH V2 01/13] perf/x86/intel/uncore: Move uncore discovery init struct to header Zide Chen
2026-01-04 1:47 ` Mi, Dapeng
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 098fe55a450b280d8a8584b2511634e1236ba96d
Gitweb: https://git.kernel.org/tip/098fe55a450b280d8a8584b2511634e1236ba96d
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:18 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:23 +01:00
perf/x86/intel/uncore: Move uncore discovery init struct to header
The discovery base MSR or PCI device is platform-specific and must be
defined statically in the per-platform init table and passed to the
discovery code.
Move the definition of struct intel_uncore_init_fun to uncore.h so it
can be accessed by discovery code, and rename it to reflect that it
now carries more than just init callbacks.
Shorten intel_uncore_has_discovery_tables[_pci/msr] to
uncore_discovery[_pci/msr] for improved readability and alignment.
Drop the `intel_` prefix from new names since the code is under the
intel directory and long identifiers make alignment harder. Further
cleanups will continue removing `intel_` prefixes.
No functional change intended.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-2-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 72 +++++++++--------------
arch/x86/events/intel/uncore.h | 10 +++-
arch/x86/events/intel/uncore_discovery.c | 12 ++--
arch/x86/events/intel/uncore_discovery.h | 2 +-
4 files changed, 49 insertions(+), 47 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index e228e56..cd56129 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1697,133 +1697,123 @@ err:
return ret;
}
-struct intel_uncore_init_fun {
- void (*cpu_init)(void);
- int (*pci_init)(void);
- void (*mmio_init)(void);
- /* Discovery table is required */
- bool use_discovery;
- /* The units in the discovery table should be ignored. */
- int *uncore_units_ignore;
-};
-
-static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
+static const struct uncore_plat_init nhm_uncore_init __initconst = {
.cpu_init = nhm_uncore_cpu_init,
};
-static const struct intel_uncore_init_fun snb_uncore_init __initconst = {
+static const struct uncore_plat_init snb_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = snb_uncore_pci_init,
};
-static const struct intel_uncore_init_fun ivb_uncore_init __initconst = {
+static const struct uncore_plat_init ivb_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = ivb_uncore_pci_init,
};
-static const struct intel_uncore_init_fun hsw_uncore_init __initconst = {
+static const struct uncore_plat_init hsw_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = hsw_uncore_pci_init,
};
-static const struct intel_uncore_init_fun bdw_uncore_init __initconst = {
+static const struct uncore_plat_init bdw_uncore_init __initconst = {
.cpu_init = snb_uncore_cpu_init,
.pci_init = bdw_uncore_pci_init,
};
-static const struct intel_uncore_init_fun snbep_uncore_init __initconst = {
+static const struct uncore_plat_init snbep_uncore_init __initconst = {
.cpu_init = snbep_uncore_cpu_init,
.pci_init = snbep_uncore_pci_init,
};
-static const struct intel_uncore_init_fun nhmex_uncore_init __initconst = {
+static const struct uncore_plat_init nhmex_uncore_init __initconst = {
.cpu_init = nhmex_uncore_cpu_init,
};
-static const struct intel_uncore_init_fun ivbep_uncore_init __initconst = {
+static const struct uncore_plat_init ivbep_uncore_init __initconst = {
.cpu_init = ivbep_uncore_cpu_init,
.pci_init = ivbep_uncore_pci_init,
};
-static const struct intel_uncore_init_fun hswep_uncore_init __initconst = {
+static const struct uncore_plat_init hswep_uncore_init __initconst = {
.cpu_init = hswep_uncore_cpu_init,
.pci_init = hswep_uncore_pci_init,
};
-static const struct intel_uncore_init_fun bdx_uncore_init __initconst = {
+static const struct uncore_plat_init bdx_uncore_init __initconst = {
.cpu_init = bdx_uncore_cpu_init,
.pci_init = bdx_uncore_pci_init,
};
-static const struct intel_uncore_init_fun knl_uncore_init __initconst = {
+static const struct uncore_plat_init knl_uncore_init __initconst = {
.cpu_init = knl_uncore_cpu_init,
.pci_init = knl_uncore_pci_init,
};
-static const struct intel_uncore_init_fun skl_uncore_init __initconst = {
+static const struct uncore_plat_init skl_uncore_init __initconst = {
.cpu_init = skl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};
-static const struct intel_uncore_init_fun skx_uncore_init __initconst = {
+static const struct uncore_plat_init skx_uncore_init __initconst = {
.cpu_init = skx_uncore_cpu_init,
.pci_init = skx_uncore_pci_init,
};
-static const struct intel_uncore_init_fun icl_uncore_init __initconst = {
+static const struct uncore_plat_init icl_uncore_init __initconst = {
.cpu_init = icl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};
-static const struct intel_uncore_init_fun tgl_uncore_init __initconst = {
+static const struct uncore_plat_init tgl_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.mmio_init = tgl_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun tgl_l_uncore_init __initconst = {
+static const struct uncore_plat_init tgl_l_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.mmio_init = tgl_l_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun rkl_uncore_init __initconst = {
+static const struct uncore_plat_init rkl_uncore_init __initconst = {
.cpu_init = tgl_uncore_cpu_init,
.pci_init = skl_uncore_pci_init,
};
-static const struct intel_uncore_init_fun adl_uncore_init __initconst = {
+static const struct uncore_plat_init adl_uncore_init __initconst = {
.cpu_init = adl_uncore_cpu_init,
.mmio_init = adl_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun mtl_uncore_init __initconst = {
+static const struct uncore_plat_init mtl_uncore_init __initconst = {
.cpu_init = mtl_uncore_cpu_init,
.mmio_init = adl_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun lnl_uncore_init __initconst = {
+static const struct uncore_plat_init lnl_uncore_init __initconst = {
.cpu_init = lnl_uncore_cpu_init,
.mmio_init = lnl_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun ptl_uncore_init __initconst = {
+static const struct uncore_plat_init ptl_uncore_init __initconst = {
.cpu_init = ptl_uncore_cpu_init,
.mmio_init = ptl_uncore_mmio_init,
.use_discovery = true,
};
-static const struct intel_uncore_init_fun icx_uncore_init __initconst = {
+static const struct uncore_plat_init icx_uncore_init __initconst = {
.cpu_init = icx_uncore_cpu_init,
.pci_init = icx_uncore_pci_init,
.mmio_init = icx_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun snr_uncore_init __initconst = {
+static const struct uncore_plat_init snr_uncore_init __initconst = {
.cpu_init = snr_uncore_cpu_init,
.pci_init = snr_uncore_pci_init,
.mmio_init = snr_uncore_mmio_init,
};
-static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
+static const struct uncore_plat_init spr_uncore_init __initconst = {
.cpu_init = spr_uncore_cpu_init,
.pci_init = spr_uncore_pci_init,
.mmio_init = spr_uncore_mmio_init,
@@ -1831,7 +1821,7 @@ static const struct intel_uncore_init_fun spr_uncore_init __initconst = {
.uncore_units_ignore = spr_uncore_units_ignore,
};
-static const struct intel_uncore_init_fun gnr_uncore_init __initconst = {
+static const struct uncore_plat_init gnr_uncore_init __initconst = {
.cpu_init = gnr_uncore_cpu_init,
.pci_init = gnr_uncore_pci_init,
.mmio_init = gnr_uncore_mmio_init,
@@ -1839,7 +1829,7 @@ static const struct intel_uncore_init_fun gnr_uncore_init __initconst = {
.uncore_units_ignore = gnr_uncore_units_ignore,
};
-static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
+static const struct uncore_plat_init generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
.mmio_init = intel_uncore_generic_uncore_mmio_init,
@@ -1910,7 +1900,7 @@ MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
static int __init intel_uncore_init(void)
{
const struct x86_cpu_id *id;
- struct intel_uncore_init_fun *uncore_init;
+ struct uncore_plat_init *uncore_init;
int pret = 0, cret = 0, mret = 0, ret;
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
@@ -1921,16 +1911,16 @@ static int __init intel_uncore_init(void)
id = x86_match_cpu(intel_uncore_match);
if (!id) {
- if (!uncore_no_discover && intel_uncore_has_discovery_tables(NULL))
- uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
+ if (!uncore_no_discover && uncore_discovery(NULL))
+ uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
else
return -ENODEV;
} else {
- uncore_init = (struct intel_uncore_init_fun *)id->driver_data;
+ uncore_init = (struct uncore_plat_init *)id->driver_data;
if (uncore_no_discover && uncore_init->use_discovery)
return -ENODEV;
if (uncore_init->use_discovery &&
- !intel_uncore_has_discovery_tables(uncore_init->uncore_units_ignore))
+ !uncore_discovery(uncore_init))
return -ENODEV;
}
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index d8815ff..568536e 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -47,6 +47,16 @@ struct uncore_event_desc;
struct freerunning_counters;
struct intel_uncore_topology;
+struct uncore_plat_init {
+ void (*cpu_init)(void);
+ int (*pci_init)(void);
+ void (*mmio_init)(void);
+ /* Discovery table is required */
+ bool use_discovery;
+ /* The units in the discovery table should be ignored. */
+ int *uncore_units_ignore;
+};
+
struct intel_uncore_type {
const char *name;
int num_counters;
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 330bca2..97f1443 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -350,7 +350,7 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
return __parse_discovery_table(addr, die, parsed, ignore);
}
-static bool intel_uncore_has_discovery_tables_pci(int *ignore)
+static bool uncore_discovery_pci(int *ignore)
{
u32 device, val, entry_id, bar_offset;
int die, dvsec = 0, ret = true;
@@ -399,7 +399,7 @@ err:
return ret;
}
-static bool intel_uncore_has_discovery_tables_msr(int *ignore)
+static bool uncore_discovery_msr(int *ignore)
{
unsigned long *die_mask;
bool parsed = false;
@@ -432,10 +432,12 @@ static bool intel_uncore_has_discovery_tables_msr(int *ignore)
return parsed;
}
-bool intel_uncore_has_discovery_tables(int *ignore)
+bool uncore_discovery(struct uncore_plat_init *init)
{
- return intel_uncore_has_discovery_tables_msr(ignore) ||
- intel_uncore_has_discovery_tables_pci(ignore);
+ int *ignore = init ? init->uncore_units_ignore : NULL;
+
+ return uncore_discovery_msr(ignore) ||
+ uncore_discovery_pci(ignore);
}
void intel_uncore_clear_discovery_tables(void)
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index dff75c9..dfc237a 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -136,7 +136,7 @@ struct intel_uncore_discovery_type {
u16 num_units; /* number of units */
};
-bool intel_uncore_has_discovery_tables(int *ignore);
+bool uncore_discovery(struct uncore_plat_init *init);
void intel_uncore_clear_discovery_tables(void);
void intel_uncore_generic_uncore_cpu_init(void);
int intel_uncore_generic_uncore_pci_init(void);
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 02/13] perf/x86/intel/uncore: Support per-platform discovery base devices
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
2025-12-31 22:42 ` [PATCH V2 01/13] perf/x86/intel/uncore: Move uncore discovery init struct to header Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 2:00 ` Mi, Dapeng
` (2 more replies)
2025-12-31 22:42 ` [PATCH V2 03/13] perf/x86/intel/uncore: Remove has_generic_discovery_table() Zide Chen
` (11 subsequent siblings)
13 siblings, 3 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
On DMR platforms, IMH discovery tables are enumerated via PCI, while
CBB domains use MSRs, unlike earlier platforms which relied on either
PCI or MSR exclusively.
DMR also uses different MSRs and PCI devices, requiring support for
multiple, platform-specific discovery bases.
Introduce struct uncore_discovery_domain to hold the discovery base and
other domain-specific configuration.
Move uncore_units_ignore into uncore_discovery_domain so a single
structure can be passed to uncore_discovery_[pci/msr].
No functional change intended.
Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
v2:
- Introduce uncore_discovery_domain[] to support possible any
combination of MSR or PCI discovery base.
- Move has_generic_discovery_table() related code to a separate patch
for easier review.
- Update commit messages.
arch/x86/events/intel/uncore.c | 32 ++++++++-----
arch/x86/events/intel/uncore.h | 15 +++++--
arch/x86/events/intel/uncore_discovery.c | 57 +++++++++++++++---------
3 files changed, 69 insertions(+), 35 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index cd561290be8c..844030ef87c4 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1798,7 +1798,7 @@ static const struct uncore_plat_init lnl_uncore_init __initconst = {
static const struct uncore_plat_init ptl_uncore_init __initconst = {
.cpu_init = ptl_uncore_cpu_init,
.mmio_init = ptl_uncore_mmio_init,
- .use_discovery = true,
+ .domain[0].discovery_base = UNCORE_DISCOVERY_MSR,
};
static const struct uncore_plat_init icx_uncore_init __initconst = {
@@ -1817,16 +1817,18 @@ static const struct uncore_plat_init spr_uncore_init __initconst = {
.cpu_init = spr_uncore_cpu_init,
.pci_init = spr_uncore_pci_init,
.mmio_init = spr_uncore_mmio_init,
- .use_discovery = true,
- .uncore_units_ignore = spr_uncore_units_ignore,
+ .domain[0].base_is_pci = true,
+ .domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
+ .domain[0].units_ignore = spr_uncore_units_ignore,
};
static const struct uncore_plat_init gnr_uncore_init __initconst = {
.cpu_init = gnr_uncore_cpu_init,
.pci_init = gnr_uncore_pci_init,
.mmio_init = gnr_uncore_mmio_init,
- .use_discovery = true,
- .uncore_units_ignore = gnr_uncore_units_ignore,
+ .domain[0].base_is_pci = true,
+ .domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
+ .domain[0].units_ignore = gnr_uncore_units_ignore,
};
static const struct uncore_plat_init generic_uncore_init __initconst = {
@@ -1897,6 +1899,17 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
};
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
+static bool ucore_use_discovery(struct uncore_plat_init *config)
+{
+ int i;
+
+ for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++)
+ if (config->domain[i].discovery_base)
+ return true;
+
+ return false;
+}
+
static int __init intel_uncore_init(void)
{
const struct x86_cpu_id *id;
@@ -1911,15 +1924,14 @@ static int __init intel_uncore_init(void)
id = x86_match_cpu(intel_uncore_match);
if (!id) {
- if (!uncore_no_discover && uncore_discovery(NULL))
- uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
- else
+ uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
+ if (uncore_no_discover || !uncore_discovery(uncore_init))
return -ENODEV;
} else {
uncore_init = (struct uncore_plat_init *)id->driver_data;
- if (uncore_no_discover && uncore_init->use_discovery)
+ if (uncore_no_discover && ucore_use_discovery(uncore_init))
return -ENODEV;
- if (uncore_init->use_discovery &&
+ if (ucore_use_discovery(uncore_init) &&
!uncore_discovery(uncore_init))
return -ENODEV;
}
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 568536ef28ee..1574ffc7ee05 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -47,14 +47,21 @@ struct uncore_event_desc;
struct freerunning_counters;
struct intel_uncore_topology;
+struct uncore_discovery_domain {
+ /* MSR address or PCI device used as the discovery base */
+ u32 discovery_base;
+ bool base_is_pci;
+ /* The units in the discovery table should be ignored. */
+ int *units_ignore;
+};
+
+#define UNCORE_DISCOVERY_DOMAINS 2
struct uncore_plat_init {
void (*cpu_init)(void);
int (*pci_init)(void);
void (*mmio_init)(void);
- /* Discovery table is required */
- bool use_discovery;
- /* The units in the discovery table should be ignored. */
- int *uncore_units_ignore;
+
+ struct uncore_discovery_domain domain[UNCORE_DISCOVERY_DOMAINS];
};
struct intel_uncore_type {
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index d39f6a0b8cc3..3bcbf974d3a8 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -259,23 +259,24 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit,
}
static bool
-uncore_ignore_unit(struct uncore_unit_discovery *unit, int *ignore)
+uncore_ignore_unit(struct uncore_unit_discovery *unit,
+ struct uncore_discovery_domain *domain)
{
int i;
- if (!ignore)
+ if (!domain || !domain->units_ignore)
return false;
- for (i = 0; ignore[i] != UNCORE_IGNORE_END ; i++) {
- if (unit->box_type == ignore[i])
+ for (i = 0; domain->units_ignore[i] != UNCORE_IGNORE_END ; i++) {
+ if (unit->box_type == domain->units_ignore[i])
return true;
}
return false;
}
-static int __parse_discovery_table(resource_size_t addr, int die,
- bool *parsed, int *ignore)
+static int __parse_discovery_table(struct uncore_discovery_domain *domain,
+ resource_size_t addr, int die, bool *parsed)
{
struct uncore_global_discovery global;
struct uncore_unit_discovery unit;
@@ -314,7 +315,7 @@ static int __parse_discovery_table(resource_size_t addr, int die,
if (unit.access_type >= UNCORE_ACCESS_MAX)
continue;
- if (uncore_ignore_unit(&unit, ignore))
+ if (uncore_ignore_unit(&unit, domain))
continue;
uncore_insert_box_info(&unit, die);
@@ -325,9 +326,9 @@ static int __parse_discovery_table(resource_size_t addr, int die,
return 0;
}
-static int parse_discovery_table(struct pci_dev *dev, int die,
- u32 bar_offset, bool *parsed,
- int *ignore)
+static int parse_discovery_table(struct uncore_discovery_domain *domain,
+ struct pci_dev *dev, int die,
+ u32 bar_offset, bool *parsed)
{
resource_size_t addr;
u32 val;
@@ -347,17 +348,19 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
}
#endif
- return __parse_discovery_table(addr, die, parsed, ignore);
+ return __parse_discovery_table(domain, addr, die, parsed);
}
-static bool uncore_discovery_pci(int *ignore)
+static bool uncore_discovery_pci(struct uncore_discovery_domain *domain)
{
u32 device, val, entry_id, bar_offset;
int die, dvsec = 0, ret = true;
struct pci_dev *dev = NULL;
bool parsed = false;
- if (has_generic_discovery_table())
+ if (domain->discovery_base)
+ device = domain->discovery_base;
+ else if (has_generic_discovery_table())
device = UNCORE_DISCOVERY_TABLE_DEVICE;
else
device = PCI_ANY_ID;
@@ -386,7 +389,7 @@ static bool uncore_discovery_pci(int *ignore)
if (die < 0)
continue;
- parse_discovery_table(dev, die, bar_offset, &parsed, ignore);
+ parse_discovery_table(domain, dev, die, bar_offset, &parsed);
}
}
@@ -399,11 +402,11 @@ static bool uncore_discovery_pci(int *ignore)
return ret;
}
-static bool uncore_discovery_msr(int *ignore)
+static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
{
unsigned long *die_mask;
bool parsed = false;
- int cpu, die;
+ int cpu, die, msr;
u64 base;
die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
@@ -411,19 +414,22 @@ static bool uncore_discovery_msr(int *ignore)
if (!die_mask)
return false;
+ msr = domain->discovery_base ?
+ domain->discovery_base : UNCORE_DISCOVERY_MSR;
+
cpus_read_lock();
for_each_online_cpu(cpu) {
die = topology_logical_die_id(cpu);
if (__test_and_set_bit(die, die_mask))
continue;
- if (rdmsrq_safe_on_cpu(cpu, UNCORE_DISCOVERY_MSR, &base))
+ if (rdmsrq_safe_on_cpu(cpu, msr, &base))
continue;
if (!base)
continue;
- __parse_discovery_table(base, die, &parsed, ignore);
+ __parse_discovery_table(domain, base, die, &parsed);
}
cpus_read_unlock();
@@ -434,10 +440,19 @@ static bool uncore_discovery_msr(int *ignore)
bool uncore_discovery(struct uncore_plat_init *init)
{
- int *ignore = init ? init->uncore_units_ignore : NULL;
+ struct uncore_discovery_domain *domain;
+ bool ret = false;
+ int i;
- return uncore_discovery_msr(ignore) ||
- uncore_discovery_pci(ignore);
+ for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
+ domain = &init->domain[i];
+ if (!domain->base_is_pci)
+ ret |= uncore_discovery_msr(domain);
+ else
+ ret |= uncore_discovery_pci(domain);
+ }
+
+ return ret;
}
void intel_uncore_clear_discovery_tables(void)
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 02/13] perf/x86/intel/uncore: Support per-platform discovery base devices
2025-12-31 22:42 ` [PATCH V2 02/13] perf/x86/intel/uncore: Support per-platform discovery base devices Zide Chen
@ 2026-01-04 2:00 ` Mi, Dapeng
2026-01-06 11:01 ` Peter Zijlstra
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2 siblings, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:00 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> On DMR platforms, IMH discovery tables are enumerated via PCI, while
> CBB domains use MSRs, unlike earlier platforms which relied on either
> PCI or MSR exclusively.
>
> DMR also uses different MSRs and PCI devices, requiring support for
> multiple, platform-specific discovery bases.
>
> Introduce struct uncore_discovery_domain to hold the discovery base and
> other domain-specific configuration.
>
> Move uncore_units_ignore into uncore_discovery_domain so a single
> structure can be passed to uncore_discovery_[pci/msr].
>
> No functional change intended.
>
> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> v2:
> - Introduce uncore_discovery_domain[] to support possible any
> combination of MSR or PCI discovery base.
> - Move has_generic_discovery_table() related code to a separate patch
> for easier review.
> - Update commit messages.
>
> arch/x86/events/intel/uncore.c | 32 ++++++++-----
> arch/x86/events/intel/uncore.h | 15 +++++--
> arch/x86/events/intel/uncore_discovery.c | 57 +++++++++++++++---------
> 3 files changed, 69 insertions(+), 35 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index cd561290be8c..844030ef87c4 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -1798,7 +1798,7 @@ static const struct uncore_plat_init lnl_uncore_init __initconst = {
> static const struct uncore_plat_init ptl_uncore_init __initconst = {
> .cpu_init = ptl_uncore_cpu_init,
> .mmio_init = ptl_uncore_mmio_init,
> - .use_discovery = true,
> + .domain[0].discovery_base = UNCORE_DISCOVERY_MSR,
> };
>
> static const struct uncore_plat_init icx_uncore_init __initconst = {
> @@ -1817,16 +1817,18 @@ static const struct uncore_plat_init spr_uncore_init __initconst = {
> .cpu_init = spr_uncore_cpu_init,
> .pci_init = spr_uncore_pci_init,
> .mmio_init = spr_uncore_mmio_init,
> - .use_discovery = true,
> - .uncore_units_ignore = spr_uncore_units_ignore,
> + .domain[0].base_is_pci = true,
> + .domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
> + .domain[0].units_ignore = spr_uncore_units_ignore,
> };
>
> static const struct uncore_plat_init gnr_uncore_init __initconst = {
> .cpu_init = gnr_uncore_cpu_init,
> .pci_init = gnr_uncore_pci_init,
> .mmio_init = gnr_uncore_mmio_init,
> - .use_discovery = true,
> - .uncore_units_ignore = gnr_uncore_units_ignore,
> + .domain[0].base_is_pci = true,
> + .domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
> + .domain[0].units_ignore = gnr_uncore_units_ignore,
> };
>
> static const struct uncore_plat_init generic_uncore_init __initconst = {
> @@ -1897,6 +1899,17 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
> };
> MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
>
> +static bool ucore_use_discovery(struct uncore_plat_init *config)
> +{
> + int i;
> +
> + for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++)
> + if (config->domain[i].discovery_base)
> + return true;
> +
> + return false;
> +}
> +
> static int __init intel_uncore_init(void)
> {
> const struct x86_cpu_id *id;
> @@ -1911,15 +1924,14 @@ static int __init intel_uncore_init(void)
>
> id = x86_match_cpu(intel_uncore_match);
> if (!id) {
> - if (!uncore_no_discover && uncore_discovery(NULL))
> - uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
> - else
> + uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
> + if (uncore_no_discover || !uncore_discovery(uncore_init))
> return -ENODEV;
> } else {
> uncore_init = (struct uncore_plat_init *)id->driver_data;
> - if (uncore_no_discover && uncore_init->use_discovery)
> + if (uncore_no_discover && ucore_use_discovery(uncore_init))
> return -ENODEV;
> - if (uncore_init->use_discovery &&
> + if (ucore_use_discovery(uncore_init) &&
> !uncore_discovery(uncore_init))
> return -ENODEV;
> }
> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
> index 568536ef28ee..1574ffc7ee05 100644
> --- a/arch/x86/events/intel/uncore.h
> +++ b/arch/x86/events/intel/uncore.h
> @@ -47,14 +47,21 @@ struct uncore_event_desc;
> struct freerunning_counters;
> struct intel_uncore_topology;
>
> +struct uncore_discovery_domain {
> + /* MSR address or PCI device used as the discovery base */
> + u32 discovery_base;
> + bool base_is_pci;
> + /* The units in the discovery table should be ignored. */
> + int *units_ignore;
> +};
> +
> +#define UNCORE_DISCOVERY_DOMAINS 2
> struct uncore_plat_init {
> void (*cpu_init)(void);
> int (*pci_init)(void);
> void (*mmio_init)(void);
> - /* Discovery table is required */
> - bool use_discovery;
> - /* The units in the discovery table should be ignored. */
> - int *uncore_units_ignore;
> +
> + struct uncore_discovery_domain domain[UNCORE_DISCOVERY_DOMAINS];
> };
>
> struct intel_uncore_type {
> diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
> index d39f6a0b8cc3..3bcbf974d3a8 100644
> --- a/arch/x86/events/intel/uncore_discovery.c
> +++ b/arch/x86/events/intel/uncore_discovery.c
> @@ -259,23 +259,24 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit,
> }
>
> static bool
> -uncore_ignore_unit(struct uncore_unit_discovery *unit, int *ignore)
> +uncore_ignore_unit(struct uncore_unit_discovery *unit,
> + struct uncore_discovery_domain *domain)
> {
> int i;
>
> - if (!ignore)
> + if (!domain || !domain->units_ignore)
> return false;
>
> - for (i = 0; ignore[i] != UNCORE_IGNORE_END ; i++) {
> - if (unit->box_type == ignore[i])
> + for (i = 0; domain->units_ignore[i] != UNCORE_IGNORE_END ; i++) {
> + if (unit->box_type == domain->units_ignore[i])
> return true;
> }
>
> return false;
> }
>
> -static int __parse_discovery_table(resource_size_t addr, int die,
> - bool *parsed, int *ignore)
> +static int __parse_discovery_table(struct uncore_discovery_domain *domain,
> + resource_size_t addr, int die, bool *parsed)
> {
> struct uncore_global_discovery global;
> struct uncore_unit_discovery unit;
> @@ -314,7 +315,7 @@ static int __parse_discovery_table(resource_size_t addr, int die,
> if (unit.access_type >= UNCORE_ACCESS_MAX)
> continue;
>
> - if (uncore_ignore_unit(&unit, ignore))
> + if (uncore_ignore_unit(&unit, domain))
> continue;
>
> uncore_insert_box_info(&unit, die);
> @@ -325,9 +326,9 @@ static int __parse_discovery_table(resource_size_t addr, int die,
> return 0;
> }
>
> -static int parse_discovery_table(struct pci_dev *dev, int die,
> - u32 bar_offset, bool *parsed,
> - int *ignore)
> +static int parse_discovery_table(struct uncore_discovery_domain *domain,
> + struct pci_dev *dev, int die,
> + u32 bar_offset, bool *parsed)
> {
> resource_size_t addr;
> u32 val;
> @@ -347,17 +348,19 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
> }
> #endif
>
> - return __parse_discovery_table(addr, die, parsed, ignore);
> + return __parse_discovery_table(domain, addr, die, parsed);
> }
>
> -static bool uncore_discovery_pci(int *ignore)
> +static bool uncore_discovery_pci(struct uncore_discovery_domain *domain)
> {
> u32 device, val, entry_id, bar_offset;
> int die, dvsec = 0, ret = true;
> struct pci_dev *dev = NULL;
> bool parsed = false;
>
> - if (has_generic_discovery_table())
> + if (domain->discovery_base)
> + device = domain->discovery_base;
> + else if (has_generic_discovery_table())
> device = UNCORE_DISCOVERY_TABLE_DEVICE;
> else
> device = PCI_ANY_ID;
> @@ -386,7 +389,7 @@ static bool uncore_discovery_pci(int *ignore)
> if (die < 0)
> continue;
>
> - parse_discovery_table(dev, die, bar_offset, &parsed, ignore);
> + parse_discovery_table(domain, dev, die, bar_offset, &parsed);
> }
> }
>
> @@ -399,11 +402,11 @@ static bool uncore_discovery_pci(int *ignore)
> return ret;
> }
>
> -static bool uncore_discovery_msr(int *ignore)
> +static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
> {
> unsigned long *die_mask;
> bool parsed = false;
> - int cpu, die;
> + int cpu, die, msr;
> u64 base;
>
> die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
> @@ -411,19 +414,22 @@ static bool uncore_discovery_msr(int *ignore)
> if (!die_mask)
> return false;
>
> + msr = domain->discovery_base ?
> + domain->discovery_base : UNCORE_DISCOVERY_MSR;
> +
> cpus_read_lock();
> for_each_online_cpu(cpu) {
> die = topology_logical_die_id(cpu);
> if (__test_and_set_bit(die, die_mask))
> continue;
>
> - if (rdmsrq_safe_on_cpu(cpu, UNCORE_DISCOVERY_MSR, &base))
> + if (rdmsrq_safe_on_cpu(cpu, msr, &base))
> continue;
>
> if (!base)
> continue;
>
> - __parse_discovery_table(base, die, &parsed, ignore);
> + __parse_discovery_table(domain, base, die, &parsed);
> }
>
> cpus_read_unlock();
> @@ -434,10 +440,19 @@ static bool uncore_discovery_msr(int *ignore)
>
> bool uncore_discovery(struct uncore_plat_init *init)
> {
> - int *ignore = init ? init->uncore_units_ignore : NULL;
> + struct uncore_discovery_domain *domain;
> + bool ret = false;
> + int i;
>
> - return uncore_discovery_msr(ignore) ||
> - uncore_discovery_pci(ignore);
> + for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
> + domain = &init->domain[i];
> + if (!domain->base_is_pci)
> + ret |= uncore_discovery_msr(domain);
> + else
> + ret |= uncore_discovery_pci(domain);
> + }
> +
> + return ret;
> }
>
> void intel_uncore_clear_discovery_tables(void)
LGTM.
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 02/13] perf/x86/intel/uncore: Support per-platform discovery base devices
2025-12-31 22:42 ` [PATCH V2 02/13] perf/x86/intel/uncore: Support per-platform discovery base devices Zide Chen
2026-01-04 2:00 ` Mi, Dapeng
@ 2026-01-06 11:01 ` Peter Zijlstra
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2 siblings, 0 replies; 51+ messages in thread
From: Peter Zijlstra @ 2026-01-06 11:01 UTC (permalink / raw)
To: Zide Chen
Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Ian Rogers,
Adrian Hunter, Alexander Shishkin, Andi Kleen, Eranian Stephane,
linux-kernel, linux-perf-users, Dapeng Mi, Xudong Hao,
Falcon Thomas
On Wed, Dec 31, 2025 at 02:42:19PM -0800, Zide Chen wrote:
> @@ -1897,6 +1899,17 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
> };
> MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
>
> +static bool ucore_use_discovery(struct uncore_plat_init *config)
> +{
> + int i;
> +
> + for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++)
> + if (config->domain[i].discovery_base)
> + return true;
> +
> + return false;
> +}
> +
> static int __init intel_uncore_init(void)
> {
> const struct x86_cpu_id *id;
> @@ -1911,15 +1924,14 @@ static int __init intel_uncore_init(void)
>
> id = x86_match_cpu(intel_uncore_match);
> if (!id) {
> - if (!uncore_no_discover && uncore_discovery(NULL))
> - uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
> - else
> + uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
> + if (uncore_no_discover || !uncore_discovery(uncore_init))
> return -ENODEV;
> } else {
> uncore_init = (struct uncore_plat_init *)id->driver_data;
> - if (uncore_no_discover && uncore_init->use_discovery)
> + if (uncore_no_discover && ucore_use_discovery(uncore_init))
> return -ENODEV;
> - if (uncore_init->use_discovery &&
> + if (ucore_use_discovery(uncore_init) &&
> !uncore_discovery(uncore_init))
> return -ENODEV;
> }
I got triggered by that naming oddity, but then couldn't help but also
fix the lack of { } and then use for-scoped variables.
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1899,13 +1899,12 @@ static const struct x86_cpu_id intel_unc
};
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
-static bool ucore_use_discovery(struct uncore_plat_init *config)
+static bool uncore_use_discovery(struct uncore_plat_init *config)
{
- int i;
-
- for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++)
+ for (int i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
if (config->domain[i].discovery_base)
return true;
+ }
return false;
}
@@ -1929,9 +1928,9 @@ static int __init intel_uncore_init(void
return -ENODEV;
} else {
uncore_init = (struct uncore_plat_init *)id->driver_data;
- if (uncore_no_discover && ucore_use_discovery(uncore_init))
+ if (uncore_no_discover && uncore_use_discovery(uncore_init))
return -ENODEV;
- if (ucore_use_discovery(uncore_init) &&
+ if (uncore_use_discovery(uncore_init) &&
!uncore_discovery(uncore_init))
return -ENODEV;
}
^ permalink raw reply [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Support per-platform discovery base devices
2025-12-31 22:42 ` [PATCH V2 02/13] perf/x86/intel/uncore: Support per-platform discovery base devices Zide Chen
2026-01-04 2:00 ` Mi, Dapeng
2026-01-06 11:01 ` Peter Zijlstra
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
2 siblings, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Dapeng Mi, Zide Chen, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: e75462f6c7eaa5affd922c9a14591cdd5e3ab63d
Gitweb: https://git.kernel.org/tip/e75462f6c7eaa5affd922c9a14591cdd5e3ab63d
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:19 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:23 +01:00
perf/x86/intel/uncore: Support per-platform discovery base devices
On DMR platforms, IMH discovery tables are enumerated via PCI, while
CBB domains use MSRs, unlike earlier platforms which relied on either
PCI or MSR exclusively.
DMR also uses different MSRs and PCI devices, requiring support for
multiple, platform-specific discovery bases.
Introduce struct uncore_discovery_domain to hold the discovery base and
other domain-specific configuration.
Move uncore_units_ignore into uncore_discovery_domain so a single
structure can be passed to uncore_discovery_[pci/msr].
No functional change intended.
Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-3-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 31 ++++++++-----
arch/x86/events/intel/uncore.h | 15 ++++--
arch/x86/events/intel/uncore_discovery.c | 57 ++++++++++++++---------
3 files changed, 68 insertions(+), 35 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index cd56129..78a03af 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1798,7 +1798,7 @@ static const struct uncore_plat_init lnl_uncore_init __initconst = {
static const struct uncore_plat_init ptl_uncore_init __initconst = {
.cpu_init = ptl_uncore_cpu_init,
.mmio_init = ptl_uncore_mmio_init,
- .use_discovery = true,
+ .domain[0].discovery_base = UNCORE_DISCOVERY_MSR,
};
static const struct uncore_plat_init icx_uncore_init __initconst = {
@@ -1817,16 +1817,18 @@ static const struct uncore_plat_init spr_uncore_init __initconst = {
.cpu_init = spr_uncore_cpu_init,
.pci_init = spr_uncore_pci_init,
.mmio_init = spr_uncore_mmio_init,
- .use_discovery = true,
- .uncore_units_ignore = spr_uncore_units_ignore,
+ .domain[0].base_is_pci = true,
+ .domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
+ .domain[0].units_ignore = spr_uncore_units_ignore,
};
static const struct uncore_plat_init gnr_uncore_init __initconst = {
.cpu_init = gnr_uncore_cpu_init,
.pci_init = gnr_uncore_pci_init,
.mmio_init = gnr_uncore_mmio_init,
- .use_discovery = true,
- .uncore_units_ignore = gnr_uncore_units_ignore,
+ .domain[0].base_is_pci = true,
+ .domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
+ .domain[0].units_ignore = gnr_uncore_units_ignore,
};
static const struct uncore_plat_init generic_uncore_init __initconst = {
@@ -1897,6 +1899,16 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
};
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
+static bool uncore_use_discovery(struct uncore_plat_init *config)
+{
+ for (int i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
+ if (config->domain[i].discovery_base)
+ return true;
+ }
+
+ return false;
+}
+
static int __init intel_uncore_init(void)
{
const struct x86_cpu_id *id;
@@ -1911,15 +1923,14 @@ static int __init intel_uncore_init(void)
id = x86_match_cpu(intel_uncore_match);
if (!id) {
- if (!uncore_no_discover && uncore_discovery(NULL))
- uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
- else
+ uncore_init = (struct uncore_plat_init *)&generic_uncore_init;
+ if (uncore_no_discover || !uncore_discovery(uncore_init))
return -ENODEV;
} else {
uncore_init = (struct uncore_plat_init *)id->driver_data;
- if (uncore_no_discover && uncore_init->use_discovery)
+ if (uncore_no_discover && uncore_use_discovery(uncore_init))
return -ENODEV;
- if (uncore_init->use_discovery &&
+ if (uncore_use_discovery(uncore_init) &&
!uncore_discovery(uncore_init))
return -ENODEV;
}
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 568536e..1574ffc 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -47,14 +47,21 @@ struct uncore_event_desc;
struct freerunning_counters;
struct intel_uncore_topology;
+struct uncore_discovery_domain {
+ /* MSR address or PCI device used as the discovery base */
+ u32 discovery_base;
+ bool base_is_pci;
+ /* The units in the discovery table should be ignored. */
+ int *units_ignore;
+};
+
+#define UNCORE_DISCOVERY_DOMAINS 2
struct uncore_plat_init {
void (*cpu_init)(void);
int (*pci_init)(void);
void (*mmio_init)(void);
- /* Discovery table is required */
- bool use_discovery;
- /* The units in the discovery table should be ignored. */
- int *uncore_units_ignore;
+
+ struct uncore_discovery_domain domain[UNCORE_DISCOVERY_DOMAINS];
};
struct intel_uncore_type {
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 97f1443..25b6a65 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -259,23 +259,24 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit,
}
static bool
-uncore_ignore_unit(struct uncore_unit_discovery *unit, int *ignore)
+uncore_ignore_unit(struct uncore_unit_discovery *unit,
+ struct uncore_discovery_domain *domain)
{
int i;
- if (!ignore)
+ if (!domain || !domain->units_ignore)
return false;
- for (i = 0; ignore[i] != UNCORE_IGNORE_END ; i++) {
- if (unit->box_type == ignore[i])
+ for (i = 0; domain->units_ignore[i] != UNCORE_IGNORE_END ; i++) {
+ if (unit->box_type == domain->units_ignore[i])
return true;
}
return false;
}
-static int __parse_discovery_table(resource_size_t addr, int die,
- bool *parsed, int *ignore)
+static int __parse_discovery_table(struct uncore_discovery_domain *domain,
+ resource_size_t addr, int die, bool *parsed)
{
struct uncore_global_discovery global;
struct uncore_unit_discovery unit;
@@ -314,7 +315,7 @@ static int __parse_discovery_table(resource_size_t addr, int die,
if (unit.access_type >= UNCORE_ACCESS_MAX)
continue;
- if (uncore_ignore_unit(&unit, ignore))
+ if (uncore_ignore_unit(&unit, domain))
continue;
uncore_insert_box_info(&unit, die);
@@ -325,9 +326,9 @@ static int __parse_discovery_table(resource_size_t addr, int die,
return 0;
}
-static int parse_discovery_table(struct pci_dev *dev, int die,
- u32 bar_offset, bool *parsed,
- int *ignore)
+static int parse_discovery_table(struct uncore_discovery_domain *domain,
+ struct pci_dev *dev, int die,
+ u32 bar_offset, bool *parsed)
{
resource_size_t addr;
u32 val;
@@ -347,17 +348,19 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
}
#endif
- return __parse_discovery_table(addr, die, parsed, ignore);
+ return __parse_discovery_table(domain, addr, die, parsed);
}
-static bool uncore_discovery_pci(int *ignore)
+static bool uncore_discovery_pci(struct uncore_discovery_domain *domain)
{
u32 device, val, entry_id, bar_offset;
int die, dvsec = 0, ret = true;
struct pci_dev *dev = NULL;
bool parsed = false;
- if (has_generic_discovery_table())
+ if (domain->discovery_base)
+ device = domain->discovery_base;
+ else if (has_generic_discovery_table())
device = UNCORE_DISCOVERY_TABLE_DEVICE;
else
device = PCI_ANY_ID;
@@ -386,7 +389,7 @@ static bool uncore_discovery_pci(int *ignore)
if (die < 0)
continue;
- parse_discovery_table(dev, die, bar_offset, &parsed, ignore);
+ parse_discovery_table(domain, dev, die, bar_offset, &parsed);
}
}
@@ -399,11 +402,11 @@ err:
return ret;
}
-static bool uncore_discovery_msr(int *ignore)
+static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
{
unsigned long *die_mask;
bool parsed = false;
- int cpu, die;
+ int cpu, die, msr;
u64 base;
die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
@@ -411,19 +414,22 @@ static bool uncore_discovery_msr(int *ignore)
if (!die_mask)
return false;
+ msr = domain->discovery_base ?
+ domain->discovery_base : UNCORE_DISCOVERY_MSR;
+
cpus_read_lock();
for_each_online_cpu(cpu) {
die = topology_logical_die_id(cpu);
if (__test_and_set_bit(die, die_mask))
continue;
- if (rdmsrq_safe_on_cpu(cpu, UNCORE_DISCOVERY_MSR, &base))
+ if (rdmsrq_safe_on_cpu(cpu, msr, &base))
continue;
if (!base)
continue;
- __parse_discovery_table(base, die, &parsed, ignore);
+ __parse_discovery_table(domain, base, die, &parsed);
}
cpus_read_unlock();
@@ -434,10 +440,19 @@ static bool uncore_discovery_msr(int *ignore)
bool uncore_discovery(struct uncore_plat_init *init)
{
- int *ignore = init ? init->uncore_units_ignore : NULL;
+ struct uncore_discovery_domain *domain;
+ bool ret = false;
+ int i;
- return uncore_discovery_msr(ignore) ||
- uncore_discovery_pci(ignore);
+ for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
+ domain = &init->domain[i];
+ if (!domain->base_is_pci)
+ ret |= uncore_discovery_msr(domain);
+ else
+ ret |= uncore_discovery_pci(domain);
+ }
+
+ return ret;
}
void intel_uncore_clear_discovery_tables(void)
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 03/13] perf/x86/intel/uncore: Remove has_generic_discovery_table()
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
2025-12-31 22:42 ` [PATCH V2 01/13] perf/x86/intel/uncore: Move uncore discovery init struct to header Zide Chen
2025-12-31 22:42 ` [PATCH V2 02/13] perf/x86/intel/uncore: Support per-platform discovery base devices Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 2:03 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 04/13] perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids Zide Chen
` (10 subsequent siblings)
13 siblings, 2 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
In the !x86_match_cpu() fallback path, has_generic_discovery_table()
is removed because it does not handle multiple PCI devices. Instead,
use PCI_ANY_ID in generic_uncore_init[] to probe all PCI devices.
For MSR portals, only probe MSR 0x201e to keep the fallback simple, as
this path is best-effort only.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2: Separate patch from [PATCH V1 1/7]
- Move has_generic_discovery_table() related code to its own patch for
easier review.
arch/x86/events/intel/uncore.c | 3 ++
arch/x86/events/intel/uncore_discovery.c | 42 +++++-------------------
2 files changed, 12 insertions(+), 33 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 844030ef87c4..2a1c6dce8a35 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1835,6 +1835,9 @@ static const struct uncore_plat_init generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
.mmio_init = intel_uncore_generic_uncore_mmio_init,
+ .domain[0].base_is_pci = true,
+ .domain[0].discovery_base = PCI_ANY_ID,
+ .domain[1].discovery_base = UNCORE_DISCOVERY_MSR,
};
static const struct x86_cpu_id intel_uncore_match[] __initconst = {
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 3bcbf974d3a8..6f409e0b4722 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -12,24 +12,6 @@
static struct rb_root discovery_tables = RB_ROOT;
static int num_discovered_types[UNCORE_ACCESS_MAX];
-static bool has_generic_discovery_table(void)
-{
- struct pci_dev *dev;
- int dvsec;
-
- dev = pci_get_device(PCI_VENDOR_ID_INTEL, UNCORE_DISCOVERY_TABLE_DEVICE, NULL);
- if (!dev)
- return false;
-
- /* A discovery table device has the unique capability ID. */
- dvsec = pci_find_next_ext_capability(dev, 0, UNCORE_EXT_CAP_ID_DISCOVERY);
- pci_dev_put(dev);
- if (dvsec)
- return true;
-
- return false;
-}
-
static int logical_die_id;
static int get_device_die_id(struct pci_dev *dev)
@@ -358,12 +340,7 @@ static bool uncore_discovery_pci(struct uncore_discovery_domain *domain)
struct pci_dev *dev = NULL;
bool parsed = false;
- if (domain->discovery_base)
- device = domain->discovery_base;
- else if (has_generic_discovery_table())
- device = UNCORE_DISCOVERY_TABLE_DEVICE;
- else
- device = PCI_ANY_ID;
+ device = domain->discovery_base;
/*
* Start a new search and iterates through the list of
@@ -406,7 +383,7 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
{
unsigned long *die_mask;
bool parsed = false;
- int cpu, die, msr;
+ int cpu, die;
u64 base;
die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
@@ -414,16 +391,13 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
if (!die_mask)
return false;
- msr = domain->discovery_base ?
- domain->discovery_base : UNCORE_DISCOVERY_MSR;
-
cpus_read_lock();
for_each_online_cpu(cpu) {
die = topology_logical_die_id(cpu);
if (__test_and_set_bit(die, die_mask))
continue;
- if (rdmsrq_safe_on_cpu(cpu, msr, &base))
+ if (rdmsrq_safe_on_cpu(cpu, domain->discovery_base, &base))
continue;
if (!base)
@@ -446,10 +420,12 @@ bool uncore_discovery(struct uncore_plat_init *init)
for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
domain = &init->domain[i];
- if (!domain->base_is_pci)
- ret |= uncore_discovery_msr(domain);
- else
- ret |= uncore_discovery_pci(domain);
+ if (domain->discovery_base) {
+ if (!domain->base_is_pci)
+ ret |= uncore_discovery_msr(domain);
+ else
+ ret |= uncore_discovery_pci(domain);
+ }
}
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 03/13] perf/x86/intel/uncore: Remove has_generic_discovery_table()
2025-12-31 22:42 ` [PATCH V2 03/13] perf/x86/intel/uncore: Remove has_generic_discovery_table() Zide Chen
@ 2026-01-04 2:03 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:03 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> In the !x86_match_cpu() fallback path, has_generic_discovery_table()
> is removed because it does not handle multiple PCI devices. Instead,
> use PCI_ANY_ID in generic_uncore_init[] to probe all PCI devices.
>
> For MSR portals, only probe MSR 0x201e to keep the fallback simple, as
> this path is best-effort only.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2: Separate patch from [PATCH V1 1/7]
> - Move has_generic_discovery_table() related code to its own patch for
> easier review.
>
> arch/x86/events/intel/uncore.c | 3 ++
> arch/x86/events/intel/uncore_discovery.c | 42 +++++-------------------
> 2 files changed, 12 insertions(+), 33 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 844030ef87c4..2a1c6dce8a35 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -1835,6 +1835,9 @@ static const struct uncore_plat_init generic_uncore_init __initconst = {
> .cpu_init = intel_uncore_generic_uncore_cpu_init,
> .pci_init = intel_uncore_generic_uncore_pci_init,
> .mmio_init = intel_uncore_generic_uncore_mmio_init,
> + .domain[0].base_is_pci = true,
> + .domain[0].discovery_base = PCI_ANY_ID,
> + .domain[1].discovery_base = UNCORE_DISCOVERY_MSR,
> };
>
> static const struct x86_cpu_id intel_uncore_match[] __initconst = {
> diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
> index 3bcbf974d3a8..6f409e0b4722 100644
> --- a/arch/x86/events/intel/uncore_discovery.c
> +++ b/arch/x86/events/intel/uncore_discovery.c
> @@ -12,24 +12,6 @@
> static struct rb_root discovery_tables = RB_ROOT;
> static int num_discovered_types[UNCORE_ACCESS_MAX];
>
> -static bool has_generic_discovery_table(void)
> -{
> - struct pci_dev *dev;
> - int dvsec;
> -
> - dev = pci_get_device(PCI_VENDOR_ID_INTEL, UNCORE_DISCOVERY_TABLE_DEVICE, NULL);
> - if (!dev)
> - return false;
> -
> - /* A discovery table device has the unique capability ID. */
> - dvsec = pci_find_next_ext_capability(dev, 0, UNCORE_EXT_CAP_ID_DISCOVERY);
> - pci_dev_put(dev);
> - if (dvsec)
> - return true;
> -
> - return false;
> -}
> -
> static int logical_die_id;
>
> static int get_device_die_id(struct pci_dev *dev)
> @@ -358,12 +340,7 @@ static bool uncore_discovery_pci(struct uncore_discovery_domain *domain)
> struct pci_dev *dev = NULL;
> bool parsed = false;
>
> - if (domain->discovery_base)
> - device = domain->discovery_base;
> - else if (has_generic_discovery_table())
> - device = UNCORE_DISCOVERY_TABLE_DEVICE;
> - else
> - device = PCI_ANY_ID;
> + device = domain->discovery_base;
>
> /*
> * Start a new search and iterates through the list of
> @@ -406,7 +383,7 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
> {
> unsigned long *die_mask;
> bool parsed = false;
> - int cpu, die, msr;
> + int cpu, die;
> u64 base;
>
> die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
> @@ -414,16 +391,13 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
> if (!die_mask)
> return false;
>
> - msr = domain->discovery_base ?
> - domain->discovery_base : UNCORE_DISCOVERY_MSR;
> -
> cpus_read_lock();
> for_each_online_cpu(cpu) {
> die = topology_logical_die_id(cpu);
> if (__test_and_set_bit(die, die_mask))
> continue;
>
> - if (rdmsrq_safe_on_cpu(cpu, msr, &base))
> + if (rdmsrq_safe_on_cpu(cpu, domain->discovery_base, &base))
> continue;
>
> if (!base)
> @@ -446,10 +420,12 @@ bool uncore_discovery(struct uncore_plat_init *init)
>
> for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
> domain = &init->domain[i];
> - if (!domain->base_is_pci)
> - ret |= uncore_discovery_msr(domain);
> - else
> - ret |= uncore_discovery_pci(domain);
> + if (domain->discovery_base) {
> + if (!domain->base_is_pci)
> + ret |= uncore_discovery_msr(domain);
> + else
> + ret |= uncore_discovery_pci(domain);
> + }
> }
>
> return ret;
LGTM.
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Remove has_generic_discovery_table()
2025-12-31 22:42 ` [PATCH V2 03/13] perf/x86/intel/uncore: Remove has_generic_discovery_table() Zide Chen
2026-01-04 2:03 ` Mi, Dapeng
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 1897336728b4ab0229fb73bb6f1e94cfe914afa9
Gitweb: https://git.kernel.org/tip/1897336728b4ab0229fb73bb6f1e94cfe914afa9
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:20 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:23 +01:00
perf/x86/intel/uncore: Remove has_generic_discovery_table()
In the !x86_match_cpu() fallback path, has_generic_discovery_table()
is removed because it does not handle multiple PCI devices. Instead,
use PCI_ANY_ID in generic_uncore_init[] to probe all PCI devices.
For MSR portals, only probe MSR 0x201e to keep the fallback simple, as
this path is best-effort only.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-4-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 3 ++-
arch/x86/events/intel/uncore_discovery.c | 42 ++++-------------------
2 files changed, 12 insertions(+), 33 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 78a03af..2387b1a 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1835,6 +1835,9 @@ static const struct uncore_plat_init generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
.mmio_init = intel_uncore_generic_uncore_mmio_init,
+ .domain[0].base_is_pci = true,
+ .domain[0].discovery_base = PCI_ANY_ID,
+ .domain[1].discovery_base = UNCORE_DISCOVERY_MSR,
};
static const struct x86_cpu_id intel_uncore_match[] __initconst = {
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 25b6a65..aaa0810 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -12,24 +12,6 @@
static struct rb_root discovery_tables = RB_ROOT;
static int num_discovered_types[UNCORE_ACCESS_MAX];
-static bool has_generic_discovery_table(void)
-{
- struct pci_dev *dev;
- int dvsec;
-
- dev = pci_get_device(PCI_VENDOR_ID_INTEL, UNCORE_DISCOVERY_TABLE_DEVICE, NULL);
- if (!dev)
- return false;
-
- /* A discovery table device has the unique capability ID. */
- dvsec = pci_find_next_ext_capability(dev, 0, UNCORE_EXT_CAP_ID_DISCOVERY);
- pci_dev_put(dev);
- if (dvsec)
- return true;
-
- return false;
-}
-
static int logical_die_id;
static int get_device_die_id(struct pci_dev *dev)
@@ -358,12 +340,7 @@ static bool uncore_discovery_pci(struct uncore_discovery_domain *domain)
struct pci_dev *dev = NULL;
bool parsed = false;
- if (domain->discovery_base)
- device = domain->discovery_base;
- else if (has_generic_discovery_table())
- device = UNCORE_DISCOVERY_TABLE_DEVICE;
- else
- device = PCI_ANY_ID;
+ device = domain->discovery_base;
/*
* Start a new search and iterates through the list of
@@ -406,7 +383,7 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
{
unsigned long *die_mask;
bool parsed = false;
- int cpu, die, msr;
+ int cpu, die;
u64 base;
die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
@@ -414,16 +391,13 @@ static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
if (!die_mask)
return false;
- msr = domain->discovery_base ?
- domain->discovery_base : UNCORE_DISCOVERY_MSR;
-
cpus_read_lock();
for_each_online_cpu(cpu) {
die = topology_logical_die_id(cpu);
if (__test_and_set_bit(die, die_mask))
continue;
- if (rdmsrq_safe_on_cpu(cpu, msr, &base))
+ if (rdmsrq_safe_on_cpu(cpu, domain->discovery_base, &base))
continue;
if (!base)
@@ -446,10 +420,12 @@ bool uncore_discovery(struct uncore_plat_init *init)
for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
domain = &init->domain[i];
- if (!domain->base_is_pci)
- ret |= uncore_discovery_msr(domain);
- else
- ret |= uncore_discovery_pci(domain);
+ if (domain->discovery_base) {
+ if (!domain->base_is_pci)
+ ret |= uncore_discovery_msr(domain);
+ else
+ ret |= uncore_discovery_pci(domain);
+ }
}
return ret;
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 04/13] perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (2 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 03/13] perf/x86/intel/uncore: Remove has_generic_discovery_table() Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 05/13] perf/x86/intel/uncore: Add CBB " Zide Chen
` (9 subsequent siblings)
13 siblings, 1 reply; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
DMR supports IMH PMON units for PCU, UBox, iMC, and CXL:
- PCU and UBox are same with SPR.
- iMC is similar to SPR but uses different offsets for fixed registers.
- CXL introduces a new port_enable field and changes the position of
the threshold field.
DMR also introduces additional PMON units: SCA, HAMVF, D2D_ULA, UBR,
PCIE4, CRS, CPC, ITC, OTC, CMS, and PCIE6. Among these, PCIE4 and
PCIE6 use different unit types, but share the same config register
layout, and the generic PCIe PMON events apply to both.
Additionally, ignore the broken MSE unit.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2:
- Add missing format_attr_umask in dmr_imc_uncore_formats_attr[].
- Separate dmr_uncore_imh_units_ignore[] from dmr_uncore_units_ignore[].
arch/x86/events/intel/uncore.c | 9 +
arch/x86/events/intel/uncore.h | 3 +
arch/x86/events/intel/uncore_discovery.h | 2 +
arch/x86/events/intel/uncore_snbep.c | 229 +++++++++++++++++++++++
4 files changed, 243 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 2a1c6dce8a35..dc2b2b272bc8 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1831,6 +1831,14 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
.domain[0].units_ignore = gnr_uncore_units_ignore,
};
+static const struct uncore_plat_init dmr_uncore_init __initconst = {
+ .pci_init = dmr_uncore_pci_init,
+ .mmio_init = dmr_uncore_mmio_init,
+ .domain[0].base_is_pci = true,
+ .domain[0].discovery_base = DMR_UNCORE_DISCOVERY_TABLE_DEVICE,
+ .domain[0].units_ignore = dmr_uncore_imh_units_ignore,
+};
+
static const struct uncore_plat_init generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
@@ -1898,6 +1906,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, &gnr_uncore_init),
+ X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, &dmr_uncore_init),
{},
};
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 1574ffc7ee05..1e4b3a22403c 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -614,6 +614,7 @@ extern struct pci_extra_dev *uncore_extra_pci_dev;
extern struct event_constraint uncore_constraint_empty;
extern int spr_uncore_units_ignore[];
extern int gnr_uncore_units_ignore[];
+extern int dmr_uncore_imh_units_ignore[];
/* uncore_snb.c */
int snb_uncore_pci_init(void);
@@ -662,6 +663,8 @@ void spr_uncore_mmio_init(void);
int gnr_uncore_pci_init(void);
void gnr_uncore_cpu_init(void);
void gnr_uncore_mmio_init(void);
+int dmr_uncore_pci_init(void);
+void dmr_uncore_mmio_init(void);
/* uncore_nhmex.c */
void nhmex_uncore_cpu_init(void);
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index dfc237a2b6df..618788c30ac6 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -5,6 +5,8 @@
/* Generic device ID of a discovery table device */
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
+/* Device ID used on DMR */
+#define DMR_UNCORE_DISCOVERY_TABLE_DEVICE 0x09a1
/* Capability ID for a discovery table device */
#define UNCORE_EXT_CAP_ID_DISCOVERY 0x23
/* First DVSEC offset */
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index e1f370b8d065..4b72560dc13f 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -471,6 +471,14 @@
#define SPR_C0_MSR_PMON_BOX_FILTER0 0x200e
+/* DMR */
+#define DMR_CXLCM_EVENT_MASK_EXT 0xf
+#define DMR_HAMVF_EVENT_MASK_EXT 0xffffffff
+#define DMR_PCIE4_EVENT_MASK_EXT 0xffffff
+
+#define DMR_IMC_PMON_FIXED_CTR 0x18
+#define DMR_IMC_PMON_FIXED_CTL 0x10
+
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
@@ -486,6 +494,10 @@ DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
DEFINE_UNCORE_FORMAT_ATTR(tid_en2, tid_en, "config:16");
DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(inv2, inv, "config:21");
+DEFINE_UNCORE_FORMAT_ATTR(thresh_ext, thresh_ext, "config:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(thresh10, thresh, "config:23-32");
+DEFINE_UNCORE_FORMAT_ATTR(thresh9_2, thresh, "config:23-31");
DEFINE_UNCORE_FORMAT_ATTR(thresh9, thresh, "config:24-35");
DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29");
@@ -494,6 +506,13 @@ DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31");
+DEFINE_UNCORE_FORMAT_ATTR(port_en, port_en, "config:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(rs3_sel, rs3_sel, "config:36");
+DEFINE_UNCORE_FORMAT_ATTR(rx_sel, rx_sel, "config:37");
+DEFINE_UNCORE_FORMAT_ATTR(tx_sel, tx_sel, "config:38");
+DEFINE_UNCORE_FORMAT_ATTR(iep_sel, iep_sel, "config:39");
+DEFINE_UNCORE_FORMAT_ATTR(vc_sel, vc_sel, "config:40-47");
+DEFINE_UNCORE_FORMAT_ATTR(port_sel, port_sel, "config:48-55");
DEFINE_UNCORE_FORMAT_ATTR(ch_mask, ch_mask, "config:36-43");
DEFINE_UNCORE_FORMAT_ATTR(ch_mask2, ch_mask, "config:36-47");
DEFINE_UNCORE_FORMAT_ATTR(fc_mask, fc_mask, "config:44-46");
@@ -6709,3 +6728,213 @@ void gnr_uncore_mmio_init(void)
}
/* end of GNR uncore support */
+
+/* DMR uncore support */
+#define UNCORE_DMR_NUM_UNCORE_TYPES 52
+
+static struct attribute *dmr_imc_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh10.attr,
+ NULL,
+};
+
+static const struct attribute_group dmr_imc_uncore_format_group = {
+ .name = "format",
+ .attrs = dmr_imc_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_imc = {
+ .name = "imc",
+ .fixed_ctr_bits = 48,
+ .fixed_ctr = DMR_IMC_PMON_FIXED_CTR,
+ .fixed_ctl = DMR_IMC_PMON_FIXED_CTL,
+ .ops = &spr_uncore_mmio_ops,
+ .format_group = &dmr_imc_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct attribute *dmr_sca_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask_ext5.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ NULL,
+};
+
+static const struct attribute_group dmr_sca_uncore_format_group = {
+ .name = "format",
+ .attrs = dmr_sca_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_sca = {
+ .name = "sca",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct attribute *dmr_cxlcm_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv2.attr,
+ &format_attr_thresh9_2.attr,
+ &format_attr_port_en.attr,
+ NULL,
+};
+
+static const struct attribute_group dmr_cxlcm_uncore_format_group = {
+ .name = "format",
+ .attrs = dmr_cxlcm_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_cxlcm = {
+ .name = "cxlcm",
+ .event_mask = GENERIC_PMON_RAW_EVENT_MASK,
+ .event_mask_ext = DMR_CXLCM_EVENT_MASK_EXT,
+ .format_group = &dmr_cxlcm_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_hamvf = {
+ .name = "hamvf",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_ula = {
+ .name = "ula",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_ubr = {
+ .name = "ubr",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct attribute *dmr_pcie4_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_thresh_ext.attr,
+ &format_attr_rs3_sel.attr,
+ &format_attr_rx_sel.attr,
+ &format_attr_tx_sel.attr,
+ &format_attr_iep_sel.attr,
+ &format_attr_vc_sel.attr,
+ &format_attr_port_sel.attr,
+ NULL,
+};
+
+static const struct attribute_group dmr_pcie4_uncore_format_group = {
+ .name = "format",
+ .attrs = dmr_pcie4_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_pcie4 = {
+ .name = "pcie4",
+ .event_mask_ext = DMR_PCIE4_EVENT_MASK_EXT,
+ .format_group = &dmr_pcie4_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_crs = {
+ .name = "crs",
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_cpc = {
+ .name = "cpc",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_itc = {
+ .name = "itc",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_otc = {
+ .name = "otc",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_cms = {
+ .name = "cms",
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_pcie6 = {
+ .name = "pcie6",
+ .event_mask_ext = DMR_PCIE4_EVENT_MASK_EXT,
+ .format_group = &dmr_pcie4_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type *dmr_uncores[UNCORE_DMR_NUM_UNCORE_TYPES] = {
+ NULL, NULL, NULL, NULL,
+ &spr_uncore_pcu,
+ &gnr_uncore_ubox,
+ &dmr_uncore_imc,
+ NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ &dmr_uncore_sca,
+ &dmr_uncore_cxlcm,
+ NULL, NULL, NULL,
+ NULL, NULL,
+ &dmr_uncore_hamvf,
+ NULL,
+ NULL, NULL, NULL,
+ &dmr_uncore_ula,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ &dmr_uncore_ubr,
+ NULL,
+ &dmr_uncore_pcie4,
+ &dmr_uncore_crs,
+ &dmr_uncore_cpc,
+ &dmr_uncore_itc,
+ &dmr_uncore_otc,
+ &dmr_uncore_cms,
+ &dmr_uncore_pcie6,
+};
+
+int dmr_uncore_imh_units_ignore[] = {
+ 0x13, /* MSE */
+ UNCORE_IGNORE_END
+};
+
+int dmr_uncore_pci_init(void)
+{
+ uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
+ UNCORE_DMR_NUM_UNCORE_TYPES,
+ dmr_uncores);
+ return 0;
+}
+void dmr_uncore_mmio_init(void)
+{
+ uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL,
+ UNCORE_DMR_NUM_UNCORE_TYPES,
+ dmr_uncores);
+}
+
+/* end of DMR uncore support */
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids
2025-12-31 22:42 ` [PATCH V2 04/13] perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids Zide Chen
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
0 siblings, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Zide Chen, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 6daf2c35b835da211bf70606e9f74d1af98613a9
Gitweb: https://git.kernel.org/tip/6daf2c35b835da211bf70606e9f74d1af98613a9
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:21 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:24 +01:00
perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids
DMR supports IMH PMON units for PCU, UBox, iMC, and CXL:
- PCU and UBox are same with SPR.
- iMC is similar to SPR but uses different offsets for fixed registers.
- CXL introduces a new port_enable field and changes the position of
the threshold field.
DMR also introduces additional PMON units: SCA, HAMVF, D2D_ULA, UBR,
PCIE4, CRS, CPC, ITC, OTC, CMS, and PCIE6. Among these, PCIE4 and
PCIE6 use different unit types, but share the same config register
layout, and the generic PCIe PMON events apply to both.
Additionally, ignore the broken MSE unit.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251231224233.113839-5-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 9 +-
arch/x86/events/intel/uncore.h | 3 +-
arch/x86/events/intel/uncore_discovery.h | 2 +-
arch/x86/events/intel/uncore_snbep.c | 229 ++++++++++++++++++++++-
4 files changed, 243 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 2387b1a..40cf9bf 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1831,6 +1831,14 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
.domain[0].units_ignore = gnr_uncore_units_ignore,
};
+static const struct uncore_plat_init dmr_uncore_init __initconst = {
+ .pci_init = dmr_uncore_pci_init,
+ .mmio_init = dmr_uncore_mmio_init,
+ .domain[0].base_is_pci = true,
+ .domain[0].discovery_base = DMR_UNCORE_DISCOVERY_TABLE_DEVICE,
+ .domain[0].units_ignore = dmr_uncore_imh_units_ignore,
+};
+
static const struct uncore_plat_init generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
@@ -1898,6 +1906,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &gnr_uncore_init),
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, &gnr_uncore_init),
+ X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, &dmr_uncore_init),
{},
};
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 1574ffc..1e4b3a2 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -614,6 +614,7 @@ extern struct pci_extra_dev *uncore_extra_pci_dev;
extern struct event_constraint uncore_constraint_empty;
extern int spr_uncore_units_ignore[];
extern int gnr_uncore_units_ignore[];
+extern int dmr_uncore_imh_units_ignore[];
/* uncore_snb.c */
int snb_uncore_pci_init(void);
@@ -662,6 +663,8 @@ void spr_uncore_mmio_init(void);
int gnr_uncore_pci_init(void);
void gnr_uncore_cpu_init(void);
void gnr_uncore_mmio_init(void);
+int dmr_uncore_pci_init(void);
+void dmr_uncore_mmio_init(void);
/* uncore_nhmex.c */
void nhmex_uncore_cpu_init(void);
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index dfc237a..618788c 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -5,6 +5,8 @@
/* Generic device ID of a discovery table device */
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
+/* Device ID used on DMR */
+#define DMR_UNCORE_DISCOVERY_TABLE_DEVICE 0x09a1
/* Capability ID for a discovery table device */
#define UNCORE_EXT_CAP_ID_DISCOVERY 0x23
/* First DVSEC offset */
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index e1f370b..4b72560 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -471,6 +471,14 @@
#define SPR_C0_MSR_PMON_BOX_FILTER0 0x200e
+/* DMR */
+#define DMR_CXLCM_EVENT_MASK_EXT 0xf
+#define DMR_HAMVF_EVENT_MASK_EXT 0xffffffff
+#define DMR_PCIE4_EVENT_MASK_EXT 0xffffff
+
+#define DMR_IMC_PMON_FIXED_CTR 0x18
+#define DMR_IMC_PMON_FIXED_CTL 0x10
+
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
@@ -486,6 +494,10 @@ DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
DEFINE_UNCORE_FORMAT_ATTR(tid_en2, tid_en, "config:16");
DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(inv2, inv, "config:21");
+DEFINE_UNCORE_FORMAT_ATTR(thresh_ext, thresh_ext, "config:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(thresh10, thresh, "config:23-32");
+DEFINE_UNCORE_FORMAT_ATTR(thresh9_2, thresh, "config:23-31");
DEFINE_UNCORE_FORMAT_ATTR(thresh9, thresh, "config:24-35");
DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29");
@@ -494,6 +506,13 @@ DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31");
+DEFINE_UNCORE_FORMAT_ATTR(port_en, port_en, "config:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(rs3_sel, rs3_sel, "config:36");
+DEFINE_UNCORE_FORMAT_ATTR(rx_sel, rx_sel, "config:37");
+DEFINE_UNCORE_FORMAT_ATTR(tx_sel, tx_sel, "config:38");
+DEFINE_UNCORE_FORMAT_ATTR(iep_sel, iep_sel, "config:39");
+DEFINE_UNCORE_FORMAT_ATTR(vc_sel, vc_sel, "config:40-47");
+DEFINE_UNCORE_FORMAT_ATTR(port_sel, port_sel, "config:48-55");
DEFINE_UNCORE_FORMAT_ATTR(ch_mask, ch_mask, "config:36-43");
DEFINE_UNCORE_FORMAT_ATTR(ch_mask2, ch_mask, "config:36-47");
DEFINE_UNCORE_FORMAT_ATTR(fc_mask, fc_mask, "config:44-46");
@@ -6709,3 +6728,213 @@ void gnr_uncore_mmio_init(void)
}
/* end of GNR uncore support */
+
+/* DMR uncore support */
+#define UNCORE_DMR_NUM_UNCORE_TYPES 52
+
+static struct attribute *dmr_imc_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh10.attr,
+ NULL,
+};
+
+static const struct attribute_group dmr_imc_uncore_format_group = {
+ .name = "format",
+ .attrs = dmr_imc_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_imc = {
+ .name = "imc",
+ .fixed_ctr_bits = 48,
+ .fixed_ctr = DMR_IMC_PMON_FIXED_CTR,
+ .fixed_ctl = DMR_IMC_PMON_FIXED_CTL,
+ .ops = &spr_uncore_mmio_ops,
+ .format_group = &dmr_imc_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct attribute *dmr_sca_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask_ext5.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ NULL,
+};
+
+static const struct attribute_group dmr_sca_uncore_format_group = {
+ .name = "format",
+ .attrs = dmr_sca_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_sca = {
+ .name = "sca",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct attribute *dmr_cxlcm_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv2.attr,
+ &format_attr_thresh9_2.attr,
+ &format_attr_port_en.attr,
+ NULL,
+};
+
+static const struct attribute_group dmr_cxlcm_uncore_format_group = {
+ .name = "format",
+ .attrs = dmr_cxlcm_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_cxlcm = {
+ .name = "cxlcm",
+ .event_mask = GENERIC_PMON_RAW_EVENT_MASK,
+ .event_mask_ext = DMR_CXLCM_EVENT_MASK_EXT,
+ .format_group = &dmr_cxlcm_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_hamvf = {
+ .name = "hamvf",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_ula = {
+ .name = "ula",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_ubr = {
+ .name = "ubr",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct attribute *dmr_pcie4_uncore_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_thresh_ext.attr,
+ &format_attr_rs3_sel.attr,
+ &format_attr_rx_sel.attr,
+ &format_attr_tx_sel.attr,
+ &format_attr_iep_sel.attr,
+ &format_attr_vc_sel.attr,
+ &format_attr_port_sel.attr,
+ NULL,
+};
+
+static const struct attribute_group dmr_pcie4_uncore_format_group = {
+ .name = "format",
+ .attrs = dmr_pcie4_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_pcie4 = {
+ .name = "pcie4",
+ .event_mask_ext = DMR_PCIE4_EVENT_MASK_EXT,
+ .format_group = &dmr_pcie4_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_crs = {
+ .name = "crs",
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_cpc = {
+ .name = "cpc",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_itc = {
+ .name = "itc",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_otc = {
+ .name = "otc",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_cms = {
+ .name = "cms",
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_pcie6 = {
+ .name = "pcie6",
+ .event_mask_ext = DMR_PCIE4_EVENT_MASK_EXT,
+ .format_group = &dmr_pcie4_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type *dmr_uncores[UNCORE_DMR_NUM_UNCORE_TYPES] = {
+ NULL, NULL, NULL, NULL,
+ &spr_uncore_pcu,
+ &gnr_uncore_ubox,
+ &dmr_uncore_imc,
+ NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ &dmr_uncore_sca,
+ &dmr_uncore_cxlcm,
+ NULL, NULL, NULL,
+ NULL, NULL,
+ &dmr_uncore_hamvf,
+ NULL,
+ NULL, NULL, NULL,
+ &dmr_uncore_ula,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ &dmr_uncore_ubr,
+ NULL,
+ &dmr_uncore_pcie4,
+ &dmr_uncore_crs,
+ &dmr_uncore_cpc,
+ &dmr_uncore_itc,
+ &dmr_uncore_otc,
+ &dmr_uncore_cms,
+ &dmr_uncore_pcie6,
+};
+
+int dmr_uncore_imh_units_ignore[] = {
+ 0x13, /* MSE */
+ UNCORE_IGNORE_END
+};
+
+int dmr_uncore_pci_init(void)
+{
+ uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
+ UNCORE_DMR_NUM_UNCORE_TYPES,
+ dmr_uncores);
+ return 0;
+}
+void dmr_uncore_mmio_init(void)
+{
+ uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL,
+ UNCORE_DMR_NUM_UNCORE_TYPES,
+ dmr_uncores);
+}
+
+/* end of DMR uncore support */
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 05/13] perf/x86/intel/uncore: Add CBB PMON support for Diamond Rapids
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (3 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 04/13] perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 06/13] perf/x86/intel/uncore: Add domain global init callback Zide Chen
` (8 subsequent siblings)
13 siblings, 1 reply; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
On DMR, PMON units inside the Core Building Block (CBB) are enumerated
separately from those in the Integrated Memory and I/O Hub (IMH).
A new per-CBB MSR (0x710) is introduced for discovery table enumeration.
For counter control registers, the tid_en bit (bit 16) exists on CBO,
SBO, and Santa, but it is not used by any events. Mark this bit as
reserved.
Similarly, disallow extended umask (bits 32–63) on Santa and sNCU.
Additionally, ignore broken SB2UCIE unit.
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2:
- Rename DMR_UNCORE_DISCOVERY_MSR to CBB_UNCORE_DISCOVERY_MSR to
reflect that the MSR is not DMR-specific and allow reuse on future
platforms.
arch/x86/events/intel/uncore.c | 2 +
arch/x86/events/intel/uncore.h | 1 +
arch/x86/events/intel/uncore_discovery.h | 2 +
arch/x86/events/intel/uncore_snbep.c | 52 ++++++++++++++++++++++--
4 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index dc2b2b272bc8..1565c0418fb1 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1837,6 +1837,8 @@ static const struct uncore_plat_init dmr_uncore_init __initconst = {
.domain[0].base_is_pci = true,
.domain[0].discovery_base = DMR_UNCORE_DISCOVERY_TABLE_DEVICE,
.domain[0].units_ignore = dmr_uncore_imh_units_ignore,
+ .domain[1].discovery_base = CBB_UNCORE_DISCOVERY_MSR,
+ .domain[1].units_ignore = dmr_uncore_cbb_units_ignore,
};
static const struct uncore_plat_init generic_uncore_init __initconst = {
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 1e4b3a22403c..83d01a9cefc0 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -615,6 +615,7 @@ extern struct event_constraint uncore_constraint_empty;
extern int spr_uncore_units_ignore[];
extern int gnr_uncore_units_ignore[];
extern int dmr_uncore_imh_units_ignore[];
+extern int dmr_uncore_cbb_units_ignore[];
/* uncore_snb.c */
int snb_uncore_pci_init(void);
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index 618788c30ac6..63b8f7634e42 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -2,6 +2,8 @@
/* Store the full address of the global discovery table */
#define UNCORE_DISCOVERY_MSR 0x201e
+/* Base address of uncore perfmon discovery table for CBB domain */
+#define CBB_UNCORE_DISCOVERY_MSR 0x710
/* Generic device ID of a discovery table device */
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 4b72560dc13f..df173534637a 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -6807,6 +6807,28 @@ static struct intel_uncore_type dmr_uncore_hamvf = {
.attr_update = uncore_alias_groups,
};
+static struct intel_uncore_type dmr_uncore_cbo = {
+ .name = "cbo",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_santa = {
+ .name = "santa",
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_cncu = {
+ .name = "cncu",
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_sncu = {
+ .name = "sncu",
+ .attr_update = uncore_alias_groups,
+};
+
static struct intel_uncore_type dmr_uncore_ula = {
.name = "ula",
.event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
@@ -6814,6 +6836,20 @@ static struct intel_uncore_type dmr_uncore_ula = {
.attr_update = uncore_alias_groups,
};
+static struct intel_uncore_type dmr_uncore_dda = {
+ .name = "dda",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_sbo = {
+ .name = "sbo",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
static struct intel_uncore_type dmr_uncore_ubr = {
.name = "ubr",
.event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
@@ -6902,10 +6938,15 @@ static struct intel_uncore_type *dmr_uncores[UNCORE_DMR_NUM_UNCORE_TYPES] = {
NULL, NULL, NULL,
NULL, NULL,
&dmr_uncore_hamvf,
- NULL,
- NULL, NULL, NULL,
+ &dmr_uncore_cbo,
+ &dmr_uncore_santa,
+ &dmr_uncore_cncu,
+ &dmr_uncore_sncu,
&dmr_uncore_ula,
- NULL, NULL, NULL, NULL,
+ &dmr_uncore_dda,
+ NULL,
+ &dmr_uncore_sbo,
+ NULL,
NULL, NULL, NULL,
&dmr_uncore_ubr,
NULL,
@@ -6923,6 +6964,11 @@ int dmr_uncore_imh_units_ignore[] = {
UNCORE_IGNORE_END
};
+int dmr_uncore_cbb_units_ignore[] = {
+ 0x25, /* SB2UCIE */
+ UNCORE_IGNORE_END
+};
+
int dmr_uncore_pci_init(void)
{
uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Add CBB PMON support for Diamond Rapids
2025-12-31 22:42 ` [PATCH V2 05/13] perf/x86/intel/uncore: Add CBB " Zide Chen
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
0 siblings, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 66e2075426f3220857eb3987c803764c82cef851
Gitweb: https://git.kernel.org/tip/66e2075426f3220857eb3987c803764c82cef851
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:22 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:24 +01:00
perf/x86/intel/uncore: Add CBB PMON support for Diamond Rapids
On DMR, PMON units inside the Core Building Block (CBB) are enumerated
separately from those in the Integrated Memory and I/O Hub (IMH).
A new per-CBB MSR (0x710) is introduced for discovery table enumeration.
For counter control registers, the tid_en bit (bit 16) exists on CBO,
SBO, and Santa, but it is not used by any events. Mark this bit as
reserved.
Similarly, disallow extended umask (bits 32–63) on Santa and sNCU.
Additionally, ignore broken SB2UCIE unit.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-6-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 2 +-
arch/x86/events/intel/uncore.h | 1 +-
arch/x86/events/intel/uncore_discovery.h | 2 +-
arch/x86/events/intel/uncore_snbep.c | 52 +++++++++++++++++++++--
4 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 40cf9bf..08e5dd4 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1837,6 +1837,8 @@ static const struct uncore_plat_init dmr_uncore_init __initconst = {
.domain[0].base_is_pci = true,
.domain[0].discovery_base = DMR_UNCORE_DISCOVERY_TABLE_DEVICE,
.domain[0].units_ignore = dmr_uncore_imh_units_ignore,
+ .domain[1].discovery_base = CBB_UNCORE_DISCOVERY_MSR,
+ .domain[1].units_ignore = dmr_uncore_cbb_units_ignore,
};
static const struct uncore_plat_init generic_uncore_init __initconst = {
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 1e4b3a2..83d01a9 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -615,6 +615,7 @@ extern struct event_constraint uncore_constraint_empty;
extern int spr_uncore_units_ignore[];
extern int gnr_uncore_units_ignore[];
extern int dmr_uncore_imh_units_ignore[];
+extern int dmr_uncore_cbb_units_ignore[];
/* uncore_snb.c */
int snb_uncore_pci_init(void);
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index 618788c..63b8f76 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -2,6 +2,8 @@
/* Store the full address of the global discovery table */
#define UNCORE_DISCOVERY_MSR 0x201e
+/* Base address of uncore perfmon discovery table for CBB domain */
+#define CBB_UNCORE_DISCOVERY_MSR 0x710
/* Generic device ID of a discovery table device */
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 4b72560..df17353 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -6807,6 +6807,28 @@ static struct intel_uncore_type dmr_uncore_hamvf = {
.attr_update = uncore_alias_groups,
};
+static struct intel_uncore_type dmr_uncore_cbo = {
+ .name = "cbo",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_santa = {
+ .name = "santa",
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_cncu = {
+ .name = "cncu",
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_sncu = {
+ .name = "sncu",
+ .attr_update = uncore_alias_groups,
+};
+
static struct intel_uncore_type dmr_uncore_ula = {
.name = "ula",
.event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
@@ -6814,6 +6836,20 @@ static struct intel_uncore_type dmr_uncore_ula = {
.attr_update = uncore_alias_groups,
};
+static struct intel_uncore_type dmr_uncore_dda = {
+ .name = "dda",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_sbo = {
+ .name = "sbo",
+ .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .format_group = &dmr_sca_uncore_format_group,
+ .attr_update = uncore_alias_groups,
+};
+
static struct intel_uncore_type dmr_uncore_ubr = {
.name = "ubr",
.event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
@@ -6902,10 +6938,15 @@ static struct intel_uncore_type *dmr_uncores[UNCORE_DMR_NUM_UNCORE_TYPES] = {
NULL, NULL, NULL,
NULL, NULL,
&dmr_uncore_hamvf,
- NULL,
- NULL, NULL, NULL,
+ &dmr_uncore_cbo,
+ &dmr_uncore_santa,
+ &dmr_uncore_cncu,
+ &dmr_uncore_sncu,
&dmr_uncore_ula,
- NULL, NULL, NULL, NULL,
+ &dmr_uncore_dda,
+ NULL,
+ &dmr_uncore_sbo,
+ NULL,
NULL, NULL, NULL,
&dmr_uncore_ubr,
NULL,
@@ -6923,6 +6964,11 @@ int dmr_uncore_imh_units_ignore[] = {
UNCORE_IGNORE_END
};
+int dmr_uncore_cbb_units_ignore[] = {
+ 0x25, /* SB2UCIE */
+ UNCORE_IGNORE_END
+};
+
int dmr_uncore_pci_init(void)
{
uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 06/13] perf/x86/intel/uncore: Add domain global init callback
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (4 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 05/13] perf/x86/intel/uncore: Add CBB " Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 2:26 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 07/13] perf/x86/intel/uncore: Add freerunning event descriptor helper macro Zide Chen
` (7 subsequent siblings)
13 siblings, 2 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
In the Intel uncore self-describing mechanism, the Global Control
Register freeze_all bit is SoC-wide and propagates to all uncore PMUs.
On Diamond Rapids, this bit is set at power-on, unlike some prior
platforms. Add a global_init callback to unfreeze all PMON units.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2: New patch
arch/x86/events/intel/uncore.c | 16 ++++++++++++++++
arch/x86/events/intel/uncore.h | 2 ++
arch/x86/events/intel/uncore_discovery.c | 3 +++
3 files changed, 21 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 1565c0418fb1..080b6870a88d 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1697,6 +1697,21 @@ static int __init uncore_mmio_init(void)
return ret;
}
+static int uncore_mmio_global_init(u64 ctl)
+{
+ void __iomem *io_addr;
+
+ io_addr = ioremap(ctl, sizeof(ctl));
+ if (!io_addr)
+ return -ENOMEM;
+
+ /* Clear bit 0, all other bits are reserved */
+ writel(0, io_addr);
+
+ iounmap(io_addr);
+ return 0;
+}
+
static const struct uncore_plat_init nhm_uncore_init __initconst = {
.cpu_init = nhm_uncore_cpu_init,
};
@@ -1839,6 +1854,7 @@ static const struct uncore_plat_init dmr_uncore_init __initconst = {
.domain[0].units_ignore = dmr_uncore_imh_units_ignore,
.domain[1].discovery_base = CBB_UNCORE_DISCOVERY_MSR,
.domain[1].units_ignore = dmr_uncore_cbb_units_ignore,
+ .domain[1].global_init = uncore_mmio_global_init,
};
static const struct uncore_plat_init generic_uncore_init __initconst = {
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 83d01a9cefc0..55e3aebf4b5e 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -51,6 +51,8 @@ struct uncore_discovery_domain {
/* MSR address or PCI device used as the discovery base */
u32 discovery_base;
bool base_is_pci;
+ int (*global_init)(u64 ctl);
+
/* The units in the discovery table should be ignored. */
int *units_ignore;
};
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 6f409e0b4722..3a5a3876b74c 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -286,6 +286,9 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
if (!io_addr)
return -ENOMEM;
+ if (domain->global_init && domain->global_init(global.ctl))
+ return -ENODEV;
+
/* Parsing Unit Discovery State */
for (i = 0; i < global.max_units; i++) {
memcpy_fromio(&unit, io_addr + (i + 1) * (global.stride * 8),
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 06/13] perf/x86/intel/uncore: Add domain global init callback
2025-12-31 22:42 ` [PATCH V2 06/13] perf/x86/intel/uncore: Add domain global init callback Zide Chen
@ 2026-01-04 2:26 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:26 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> In the Intel uncore self-describing mechanism, the Global Control
> Register freeze_all bit is SoC-wide and propagates to all uncore PMUs.
>
> On Diamond Rapids, this bit is set at power-on, unlike some prior
> platforms. Add a global_init callback to unfreeze all PMON units.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2: New patch
>
> arch/x86/events/intel/uncore.c | 16 ++++++++++++++++
> arch/x86/events/intel/uncore.h | 2 ++
> arch/x86/events/intel/uncore_discovery.c | 3 +++
> 3 files changed, 21 insertions(+)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 1565c0418fb1..080b6870a88d 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -1697,6 +1697,21 @@ static int __init uncore_mmio_init(void)
> return ret;
> }
>
> +static int uncore_mmio_global_init(u64 ctl)
> +{
> + void __iomem *io_addr;
> +
> + io_addr = ioremap(ctl, sizeof(ctl));
> + if (!io_addr)
> + return -ENOMEM;
> +
> + /* Clear bit 0, all other bits are reserved */
Better make the comment clearer, like this.
/* Clear freeze bit (bit 0) to enable all counters. */
Others look good to me.
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> + writel(0, io_addr);
> +
> + iounmap(io_addr);
> + return 0;
> +}
> +
> static const struct uncore_plat_init nhm_uncore_init __initconst = {
> .cpu_init = nhm_uncore_cpu_init,
> };
> @@ -1839,6 +1854,7 @@ static const struct uncore_plat_init dmr_uncore_init __initconst = {
> .domain[0].units_ignore = dmr_uncore_imh_units_ignore,
> .domain[1].discovery_base = CBB_UNCORE_DISCOVERY_MSR,
> .domain[1].units_ignore = dmr_uncore_cbb_units_ignore,
> + .domain[1].global_init = uncore_mmio_global_init,
> };
>
> static const struct uncore_plat_init generic_uncore_init __initconst = {
> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
> index 83d01a9cefc0..55e3aebf4b5e 100644
> --- a/arch/x86/events/intel/uncore.h
> +++ b/arch/x86/events/intel/uncore.h
> @@ -51,6 +51,8 @@ struct uncore_discovery_domain {
> /* MSR address or PCI device used as the discovery base */
> u32 discovery_base;
> bool base_is_pci;
> + int (*global_init)(u64 ctl);
> +
> /* The units in the discovery table should be ignored. */
> int *units_ignore;
> };
> diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
> index 6f409e0b4722..3a5a3876b74c 100644
> --- a/arch/x86/events/intel/uncore_discovery.c
> +++ b/arch/x86/events/intel/uncore_discovery.c
> @@ -286,6 +286,9 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
> if (!io_addr)
> return -ENOMEM;
>
> + if (domain->global_init && domain->global_init(global.ctl))
> + return -ENODEV;
> +
> /* Parsing Unit Discovery State */
> for (i = 0; i < global.max_units; i++) {
> memcpy_fromio(&unit, io_addr + (i + 1) * (global.stride * 8),
^ permalink raw reply [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Add domain global init callback
2025-12-31 22:42 ` [PATCH V2 06/13] perf/x86/intel/uncore: Add domain global init callback Zide Chen
2026-01-04 2:26 ` Mi, Dapeng
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: b575fc0e33574f3a476b68057e340ebe32d7b750
Gitweb: https://git.kernel.org/tip/b575fc0e33574f3a476b68057e340ebe32d7b750
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:23 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:24 +01:00
perf/x86/intel/uncore: Add domain global init callback
In the Intel uncore self-describing mechanism, the Global Control
Register freeze_all bit is SoC-wide and propagates to all uncore PMUs.
On Diamond Rapids, this bit is set at power-on, unlike some prior
platforms. Add a global_init callback to unfreeze all PMON units.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-7-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 16 ++++++++++++++++
arch/x86/events/intel/uncore.h | 2 ++
arch/x86/events/intel/uncore_discovery.c | 3 +++
3 files changed, 21 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 08e5dd4..25a678b 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1697,6 +1697,21 @@ err:
return ret;
}
+static int uncore_mmio_global_init(u64 ctl)
+{
+ void __iomem *io_addr;
+
+ io_addr = ioremap(ctl, sizeof(ctl));
+ if (!io_addr)
+ return -ENOMEM;
+
+ /* Clear freeze bit (0) to enable all counters. */
+ writel(0, io_addr);
+
+ iounmap(io_addr);
+ return 0;
+}
+
static const struct uncore_plat_init nhm_uncore_init __initconst = {
.cpu_init = nhm_uncore_cpu_init,
};
@@ -1839,6 +1854,7 @@ static const struct uncore_plat_init dmr_uncore_init __initconst = {
.domain[0].units_ignore = dmr_uncore_imh_units_ignore,
.domain[1].discovery_base = CBB_UNCORE_DISCOVERY_MSR,
.domain[1].units_ignore = dmr_uncore_cbb_units_ignore,
+ .domain[1].global_init = uncore_mmio_global_init,
};
static const struct uncore_plat_init generic_uncore_init __initconst = {
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 83d01a9..55e3aeb 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -51,6 +51,8 @@ struct uncore_discovery_domain {
/* MSR address or PCI device used as the discovery base */
u32 discovery_base;
bool base_is_pci;
+ int (*global_init)(u64 ctl);
+
/* The units in the discovery table should be ignored. */
int *units_ignore;
};
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index aaa0810..b465752 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -286,6 +286,9 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
if (!io_addr)
return -ENOMEM;
+ if (domain->global_init && domain->global_init(global.ctl))
+ return -ENODEV;
+
/* Parsing Unit Discovery State */
for (i = 0; i < global.max_units; i++) {
memcpy_fromio(&unit, io_addr + (i + 1) * (global.stride * 8),
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 07/13] perf/x86/intel/uncore: Add freerunning event descriptor helper macro
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (5 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 06/13] perf/x86/intel/uncore: Add domain global init callback Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 08/13] perf/x86/intel/uncore: Support IIO free-running counters on DMR Zide Chen
` (6 subsequent siblings)
13 siblings, 1 reply; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
Freerunning counter events are repetitive: the event code is fixed to
0xff, the unit is always "MiB", and the scale is identical across all
counters on a given PMON unit.
Introduce a new helper macro, INTEL_UNCORE_FR_EVENT_DESC(), to populate
the event, scale, and unit descriptor triplet. This reduces duplicated
lines and improves readability.
No functional change intended.
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
arch/x86/events/intel/uncore_snbep.c | 95 ++++++++--------------------
1 file changed, 28 insertions(+), 67 deletions(-)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index df173534637a..09a3bdbd188a 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -4068,34 +4068,24 @@ static struct freerunning_counters skx_iio_freerunning[] = {
[SKX_IIO_MSR_UTIL] = { 0xb08, 0x1, 0x10, 8, 36 },
};
+#define INTEL_UNCORE_FR_EVENT_DESC(name, umask, scl) \
+ INTEL_UNCORE_EVENT_DESC(name, \
+ "event=0xff,umask=" __stringify(umask)), \
+ INTEL_UNCORE_EVENT_DESC(name.scale, __stringify(scl)), \
+ INTEL_UNCORE_EVENT_DESC(name.unit, "MiB")
+
static struct uncore_event_desc skx_uncore_iio_freerunning_events[] = {
/* Free-Running IO CLOCKS Counter */
INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"),
/* Free-Running IIO BANDWIDTH Counters */
- INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port0, "event=0xff,umask=0x24"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port1, "event=0xff,umask=0x25"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port2, "event=0xff,umask=0x26"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port3, "event=0xff,umask=0x27"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit, "MiB"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port0, 0x24, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port1, 0x25, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port2, 0x26, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port3, 0x27, 3.814697266e-6),
/* Free-running IIO UTILIZATION Counters */
INTEL_UNCORE_EVENT_DESC(util_in_port0, "event=0xff,umask=0x30"),
INTEL_UNCORE_EVENT_DESC(util_out_port0, "event=0xff,umask=0x31"),
@@ -4910,30 +4900,14 @@ static struct uncore_event_desc snr_uncore_iio_freerunning_events[] = {
/* Free-Running IIO CLOCKS Counter */
INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"),
/* Free-Running IIO BANDWIDTH IN Counters */
- INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port4, "event=0xff,umask=0x24"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port5, "event=0xff,umask=0x25"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port6, "event=0xff,umask=0x26"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port7, "event=0xff,umask=0x27"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit, "MiB"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port4, 0x24, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port5, 0x25, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port6, 0x26, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port7, 0x27, 3.0517578125e-5),
{ /* end: all zeroes */ },
};
@@ -5266,12 +5240,8 @@ static struct freerunning_counters snr_imc_freerunning[] = {
static struct uncore_event_desc snr_uncore_imc_freerunning_events[] = {
INTEL_UNCORE_EVENT_DESC(dclk, "event=0xff,umask=0x10"),
- INTEL_UNCORE_EVENT_DESC(read, "event=0xff,umask=0x20"),
- INTEL_UNCORE_EVENT_DESC(read.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(read.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(write, "event=0xff,umask=0x21"),
- INTEL_UNCORE_EVENT_DESC(write.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"),
+ INTEL_UNCORE_FR_EVENT_DESC(read, 0x20, 6.103515625e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(write, 0x21, 6.103515625e-5),
{ /* end: all zeroes */ },
};
@@ -5836,19 +5806,10 @@ static struct freerunning_counters icx_imc_freerunning[] = {
static struct uncore_event_desc icx_uncore_imc_freerunning_events[] = {
INTEL_UNCORE_EVENT_DESC(dclk, "event=0xff,umask=0x10"),
- INTEL_UNCORE_EVENT_DESC(read, "event=0xff,umask=0x20"),
- INTEL_UNCORE_EVENT_DESC(read.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(read.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(write, "event=0xff,umask=0x21"),
- INTEL_UNCORE_EVENT_DESC(write.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"),
-
- INTEL_UNCORE_EVENT_DESC(ddrt_read, "event=0xff,umask=0x30"),
- INTEL_UNCORE_EVENT_DESC(ddrt_read.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(ddrt_read.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(ddrt_write, "event=0xff,umask=0x31"),
- INTEL_UNCORE_EVENT_DESC(ddrt_write.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(ddrt_write.unit, "MiB"),
+ INTEL_UNCORE_FR_EVENT_DESC(read, 0x20, 6.103515625e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(write, 0x21, 6.103515625e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(ddrt_read, 0x30, 6.103515625e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(ddrt_write, 0x31, 6.103515625e-5),
{ /* end: all zeroes */ },
};
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Add freerunning event descriptor helper macro
2025-12-31 22:42 ` [PATCH V2 07/13] perf/x86/intel/uncore: Add freerunning event descriptor helper macro Zide Chen
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
0 siblings, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 8a4bd1c0d6bb64ab4d9e94d83c40326356421a73
Gitweb: https://git.kernel.org/tip/8a4bd1c0d6bb64ab4d9e94d83c40326356421a73
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:24 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:25 +01:00
perf/x86/intel/uncore: Add freerunning event descriptor helper macro
Freerunning counter events are repetitive: the event code is fixed to
0xff, the unit is always "MiB", and the scale is identical across all
counters on a given PMON unit.
Introduce a new helper macro, INTEL_UNCORE_FR_EVENT_DESC(), to populate
the event, scale, and unit descriptor triplet. This reduces duplicated
lines and improves readability.
No functional change intended.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-8-zide.chen@intel.com
---
arch/x86/events/intel/uncore_snbep.c | 95 +++++++--------------------
1 file changed, 28 insertions(+), 67 deletions(-)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index df17353..cfb4ce3 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -4068,34 +4068,24 @@ static struct freerunning_counters skx_iio_freerunning[] = {
[SKX_IIO_MSR_UTIL] = { 0xb08, 0x1, 0x10, 8, 36 },
};
+#define INTEL_UNCORE_FR_EVENT_DESC(name, umask, scl) \
+ INTEL_UNCORE_EVENT_DESC(name, \
+ "event=0xff,umask=" __stringify(umask)),\
+ INTEL_UNCORE_EVENT_DESC(name.scale, __stringify(scl)), \
+ INTEL_UNCORE_EVENT_DESC(name.unit, "MiB")
+
static struct uncore_event_desc skx_uncore_iio_freerunning_events[] = {
/* Free-Running IO CLOCKS Counter */
INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"),
/* Free-Running IIO BANDWIDTH Counters */
- INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port0, "event=0xff,umask=0x24"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port0.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port0.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port1, "event=0xff,umask=0x25"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port1.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port1.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port2, "event=0xff,umask=0x26"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port2.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port2.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port3, "event=0xff,umask=0x27"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port3.scale, "3.814697266e-6"),
- INTEL_UNCORE_EVENT_DESC(bw_out_port3.unit, "MiB"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port0, 0x24, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port1, 0x25, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port2, 0x26, 3.814697266e-6),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port3, 0x27, 3.814697266e-6),
/* Free-running IIO UTILIZATION Counters */
INTEL_UNCORE_EVENT_DESC(util_in_port0, "event=0xff,umask=0x30"),
INTEL_UNCORE_EVENT_DESC(util_out_port0, "event=0xff,umask=0x31"),
@@ -4910,30 +4900,14 @@ static struct uncore_event_desc snr_uncore_iio_freerunning_events[] = {
/* Free-Running IIO CLOCKS Counter */
INTEL_UNCORE_EVENT_DESC(ioclk, "event=0xff,umask=0x10"),
/* Free-Running IIO BANDWIDTH IN Counters */
- INTEL_UNCORE_EVENT_DESC(bw_in_port0, "event=0xff,umask=0x20"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port0.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port0.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1, "event=0xff,umask=0x21"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port1.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2, "event=0xff,umask=0x22"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port2.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3, "event=0xff,umask=0x23"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port3.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port4, "event=0xff,umask=0x24"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port4.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port4.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port5, "event=0xff,umask=0x25"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port5.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port5.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port6, "event=0xff,umask=0x26"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port6.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port6.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port7, "event=0xff,umask=0x27"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port7.scale, "3.0517578125e-5"),
- INTEL_UNCORE_EVENT_DESC(bw_in_port7.unit, "MiB"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port4, 0x24, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port5, 0x25, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port6, 0x26, 3.0517578125e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port7, 0x27, 3.0517578125e-5),
{ /* end: all zeroes */ },
};
@@ -5266,12 +5240,8 @@ static struct freerunning_counters snr_imc_freerunning[] = {
static struct uncore_event_desc snr_uncore_imc_freerunning_events[] = {
INTEL_UNCORE_EVENT_DESC(dclk, "event=0xff,umask=0x10"),
- INTEL_UNCORE_EVENT_DESC(read, "event=0xff,umask=0x20"),
- INTEL_UNCORE_EVENT_DESC(read.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(read.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(write, "event=0xff,umask=0x21"),
- INTEL_UNCORE_EVENT_DESC(write.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"),
+ INTEL_UNCORE_FR_EVENT_DESC(read, 0x20, 6.103515625e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(write, 0x21, 6.103515625e-5),
{ /* end: all zeroes */ },
};
@@ -5836,19 +5806,10 @@ static struct freerunning_counters icx_imc_freerunning[] = {
static struct uncore_event_desc icx_uncore_imc_freerunning_events[] = {
INTEL_UNCORE_EVENT_DESC(dclk, "event=0xff,umask=0x10"),
- INTEL_UNCORE_EVENT_DESC(read, "event=0xff,umask=0x20"),
- INTEL_UNCORE_EVENT_DESC(read.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(read.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(write, "event=0xff,umask=0x21"),
- INTEL_UNCORE_EVENT_DESC(write.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"),
-
- INTEL_UNCORE_EVENT_DESC(ddrt_read, "event=0xff,umask=0x30"),
- INTEL_UNCORE_EVENT_DESC(ddrt_read.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(ddrt_read.unit, "MiB"),
- INTEL_UNCORE_EVENT_DESC(ddrt_write, "event=0xff,umask=0x31"),
- INTEL_UNCORE_EVENT_DESC(ddrt_write.scale, "6.103515625e-5"),
- INTEL_UNCORE_EVENT_DESC(ddrt_write.unit, "MiB"),
+ INTEL_UNCORE_FR_EVENT_DESC(read, 0x20, 6.103515625e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(write, 0x21, 6.103515625e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(ddrt_read, 0x30, 6.103515625e-5),
+ INTEL_UNCORE_FR_EVENT_DESC(ddrt_write, 0x31, 6.103515625e-5),
{ /* end: all zeroes */ },
};
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 08/13] perf/x86/intel/uncore: Support IIO free-running counters on DMR
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (6 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 07/13] perf/x86/intel/uncore: Add freerunning event descriptor helper macro Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 2:31 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 09/13] perf/x86/intel/uncore: Support uncore constraint ranges Zide Chen
` (5 subsequent siblings)
13 siblings, 2 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
The free-running counters for IIO uncore blocks on Diamond Rapids are
similar to Sapphire Rapids IMC freecounters, with the following
differences:
- The counters are MMIO based.
- Only a subset of IP blocks implement free-running counters:
HIOP0 (IP Base Addr: 2E7000h)
HIOP1 (IP Base Addr: 2EF000h)
HIOP3 (IP Base Addr: 2FF000h)
HIOP4 (IP Base Addr: 307000h)
- IMH2 (Secondary IMH) does not provide free-running counters.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2:
- Remove pr_warn() from dmr_uncore_freerunning_init_box().
arch/x86/events/intel/uncore_snbep.c | 118 +++++++++++++++++++++++++--
1 file changed, 113 insertions(+), 5 deletions(-)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 09a3bdbd188a..28bcccf5cdfe 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -472,10 +472,14 @@
#define SPR_C0_MSR_PMON_BOX_FILTER0 0x200e
/* DMR */
+#define DMR_IMH1_HIOP_MMIO_BASE 0x1ffff6ae7000
+#define DMR_HIOP_MMIO_SIZE 0x8000
#define DMR_CXLCM_EVENT_MASK_EXT 0xf
#define DMR_HAMVF_EVENT_MASK_EXT 0xffffffff
#define DMR_PCIE4_EVENT_MASK_EXT 0xffffff
+#define UNCORE_DMR_ITC 0x30
+
#define DMR_IMC_PMON_FIXED_CTR 0x18
#define DMR_IMC_PMON_FIXED_CTL 0x10
@@ -6442,7 +6446,11 @@ static int uncore_type_max_boxes(struct intel_uncore_type **types,
for (node = rb_first(type->boxes); node; node = rb_next(node)) {
unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
- if (unit->id > max)
+ /*
+ * on DMR IMH2, the unit id starts from 0x8000,
+ * and we don't need to count it.
+ */
+ if ((unit->id > max) && (unit->id < 0x8000))
max = unit->id;
}
return max + 1;
@@ -6930,6 +6938,101 @@ int dmr_uncore_cbb_units_ignore[] = {
UNCORE_IGNORE_END
};
+static unsigned int dmr_iio_freerunning_box_offsets[] = {
+ 0x0, 0x8000, 0x18000, 0x20000
+};
+
+static void dmr_uncore_freerunning_init_box(struct intel_uncore_box *box)
+{
+ struct intel_uncore_type *type = box->pmu->type;
+ u64 mmio_base;
+
+ if (box->pmu->pmu_idx >= type->num_boxes)
+ return;
+
+ mmio_base = DMR_IMH1_HIOP_MMIO_BASE;
+ mmio_base += dmr_iio_freerunning_box_offsets[box->pmu->pmu_idx];
+
+ box->io_addr = ioremap(mmio_base, type->mmio_map_size);
+ if (!box->io_addr)
+ pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
+}
+
+static struct intel_uncore_ops dmr_uncore_freerunning_ops = {
+ .init_box = dmr_uncore_freerunning_init_box,
+ .exit_box = uncore_mmio_exit_box,
+ .read_counter = uncore_mmio_read_counter,
+ .hw_config = uncore_freerunning_hw_config,
+};
+
+enum perf_uncore_dmr_iio_freerunning_type_id {
+ DMR_ITC_INB_DATA_BW,
+ DMR_ITC_BW_IN,
+ DMR_OTC_BW_OUT,
+ DMR_OTC_CLOCK_TICKS,
+
+ DMR_IIO_FREERUNNING_TYPE_MAX,
+};
+
+static struct freerunning_counters dmr_iio_freerunning[] = {
+ [DMR_ITC_INB_DATA_BW] = { 0x4d40, 0x8, 0, 8, 48},
+ [DMR_ITC_BW_IN] = { 0x6b00, 0x8, 0, 8, 48},
+ [DMR_OTC_BW_OUT] = { 0x6b60, 0x8, 0, 8, 48},
+ [DMR_OTC_CLOCK_TICKS] = { 0x6bb0, 0x8, 0, 1, 48},
+};
+
+static struct uncore_event_desc dmr_uncore_iio_freerunning_events[] = {
+ /* ITC Free Running Data BW counter for inbound traffic */
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port0, 0x10, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port1, 0x11, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port2, 0x12, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port3, 0x13, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port4, 0x14, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port5, 0x15, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port6, 0x16, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port7, 0x17, "3.814697266e-6"),
+
+ /* ITC Free Running BW IN counters */
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port4, 0x24, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port5, 0x25, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port6, 0x26, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port7, 0x27, "3.814697266e-6"),
+
+ /* ITC Free Running BW OUT counters */
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port0, 0x30, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port1, 0x31, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port2, 0x32, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port3, 0x33, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port4, 0x34, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port5, 0x35, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port6, 0x36, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port7, 0x37, "3.814697266e-6"),
+
+ /* Free Running Clock Counter */
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x40"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_type dmr_uncore_iio_free_running = {
+ .name = "iio_free_running",
+ .num_counters = 25,
+ .mmio_map_size = DMR_HIOP_MMIO_SIZE,
+ .num_freerunning_types = DMR_IIO_FREERUNNING_TYPE_MAX,
+ .freerunning = dmr_iio_freerunning,
+ .ops = &dmr_uncore_freerunning_ops,
+ .event_descs = dmr_uncore_iio_freerunning_events,
+ .format_group = &skx_uncore_iio_freerunning_format_group,
+};
+
+#define UNCORE_DMR_MMIO_EXTRA_UNCORES 1
+static struct intel_uncore_type *dmr_mmio_uncores[UNCORE_DMR_MMIO_EXTRA_UNCORES] = {
+ &dmr_uncore_iio_free_running,
+};
+
int dmr_uncore_pci_init(void)
{
uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
@@ -6937,11 +7040,16 @@ int dmr_uncore_pci_init(void)
dmr_uncores);
return 0;
}
+
void dmr_uncore_mmio_init(void)
{
- uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL,
- UNCORE_DMR_NUM_UNCORE_TYPES,
- dmr_uncores);
-}
+ uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
+ UNCORE_DMR_MMIO_EXTRA_UNCORES,
+ dmr_mmio_uncores,
+ UNCORE_DMR_NUM_UNCORE_TYPES,
+ dmr_uncores);
+ dmr_uncore_iio_free_running.num_boxes =
+ uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_DMR_ITC);
+}
/* end of DMR uncore support */
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 08/13] perf/x86/intel/uncore: Support IIO free-running counters on DMR
2025-12-31 22:42 ` [PATCH V2 08/13] perf/x86/intel/uncore: Support IIO free-running counters on DMR Zide Chen
@ 2026-01-04 2:31 ` Mi, Dapeng
2026-02-06 0:26 ` Chun-Tse Shao
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
1 sibling, 1 reply; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:31 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> The free-running counters for IIO uncore blocks on Diamond Rapids are
> similar to Sapphire Rapids IMC freecounters, with the following
> differences:
>
> - The counters are MMIO based.
> - Only a subset of IP blocks implement free-running counters:
> HIOP0 (IP Base Addr: 2E7000h)
> HIOP1 (IP Base Addr: 2EF000h)
> HIOP3 (IP Base Addr: 2FF000h)
> HIOP4 (IP Base Addr: 307000h)
> - IMH2 (Secondary IMH) does not provide free-running counters.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2:
> - Remove pr_warn() from dmr_uncore_freerunning_init_box().
>
> arch/x86/events/intel/uncore_snbep.c | 118 +++++++++++++++++++++++++--
> 1 file changed, 113 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
> index 09a3bdbd188a..28bcccf5cdfe 100644
> --- a/arch/x86/events/intel/uncore_snbep.c
> +++ b/arch/x86/events/intel/uncore_snbep.c
> @@ -472,10 +472,14 @@
> #define SPR_C0_MSR_PMON_BOX_FILTER0 0x200e
>
> /* DMR */
> +#define DMR_IMH1_HIOP_MMIO_BASE 0x1ffff6ae7000
> +#define DMR_HIOP_MMIO_SIZE 0x8000
> #define DMR_CXLCM_EVENT_MASK_EXT 0xf
> #define DMR_HAMVF_EVENT_MASK_EXT 0xffffffff
> #define DMR_PCIE4_EVENT_MASK_EXT 0xffffff
>
> +#define UNCORE_DMR_ITC 0x30
> +
> #define DMR_IMC_PMON_FIXED_CTR 0x18
> #define DMR_IMC_PMON_FIXED_CTL 0x10
>
> @@ -6442,7 +6446,11 @@ static int uncore_type_max_boxes(struct intel_uncore_type **types,
> for (node = rb_first(type->boxes); node; node = rb_next(node)) {
> unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
>
> - if (unit->id > max)
> + /*
> + * on DMR IMH2, the unit id starts from 0x8000,
> + * and we don't need to count it.
> + */
> + if ((unit->id > max) && (unit->id < 0x8000))
> max = unit->id;
> }
> return max + 1;
> @@ -6930,6 +6938,101 @@ int dmr_uncore_cbb_units_ignore[] = {
> UNCORE_IGNORE_END
> };
>
> +static unsigned int dmr_iio_freerunning_box_offsets[] = {
> + 0x0, 0x8000, 0x18000, 0x20000
> +};
> +
> +static void dmr_uncore_freerunning_init_box(struct intel_uncore_box *box)
> +{
> + struct intel_uncore_type *type = box->pmu->type;
> + u64 mmio_base;
> +
> + if (box->pmu->pmu_idx >= type->num_boxes)
> + return;
> +
> + mmio_base = DMR_IMH1_HIOP_MMIO_BASE;
> + mmio_base += dmr_iio_freerunning_box_offsets[box->pmu->pmu_idx];
> +
> + box->io_addr = ioremap(mmio_base, type->mmio_map_size);
> + if (!box->io_addr)
> + pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
> +}
> +
> +static struct intel_uncore_ops dmr_uncore_freerunning_ops = {
> + .init_box = dmr_uncore_freerunning_init_box,
> + .exit_box = uncore_mmio_exit_box,
> + .read_counter = uncore_mmio_read_counter,
> + .hw_config = uncore_freerunning_hw_config,
> +};
> +
> +enum perf_uncore_dmr_iio_freerunning_type_id {
> + DMR_ITC_INB_DATA_BW,
> + DMR_ITC_BW_IN,
> + DMR_OTC_BW_OUT,
> + DMR_OTC_CLOCK_TICKS,
> +
> + DMR_IIO_FREERUNNING_TYPE_MAX,
> +};
> +
> +static struct freerunning_counters dmr_iio_freerunning[] = {
> + [DMR_ITC_INB_DATA_BW] = { 0x4d40, 0x8, 0, 8, 48},
> + [DMR_ITC_BW_IN] = { 0x6b00, 0x8, 0, 8, 48},
> + [DMR_OTC_BW_OUT] = { 0x6b60, 0x8, 0, 8, 48},
> + [DMR_OTC_CLOCK_TICKS] = { 0x6bb0, 0x8, 0, 1, 48},
> +};
> +
> +static struct uncore_event_desc dmr_uncore_iio_freerunning_events[] = {
> + /* ITC Free Running Data BW counter for inbound traffic */
> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port0, 0x10, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port1, 0x11, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port2, 0x12, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port3, 0x13, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port4, 0x14, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port5, 0x15, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port6, 0x16, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port7, 0x17, "3.814697266e-6"),
> +
> + /* ITC Free Running BW IN counters */
> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port4, 0x24, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port5, 0x25, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port6, 0x26, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port7, 0x27, "3.814697266e-6"),
> +
> + /* ITC Free Running BW OUT counters */
> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port0, 0x30, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port1, 0x31, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port2, 0x32, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port3, 0x33, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port4, 0x34, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port5, 0x35, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port6, 0x36, "3.814697266e-6"),
> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port7, 0x37, "3.814697266e-6"),
> +
> + /* Free Running Clock Counter */
> + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x40"),
> + { /* end: all zeroes */ },
> +};
> +
> +static struct intel_uncore_type dmr_uncore_iio_free_running = {
> + .name = "iio_free_running",
> + .num_counters = 25,
> + .mmio_map_size = DMR_HIOP_MMIO_SIZE,
> + .num_freerunning_types = DMR_IIO_FREERUNNING_TYPE_MAX,
> + .freerunning = dmr_iio_freerunning,
> + .ops = &dmr_uncore_freerunning_ops,
> + .event_descs = dmr_uncore_iio_freerunning_events,
> + .format_group = &skx_uncore_iio_freerunning_format_group,
> +};
> +
> +#define UNCORE_DMR_MMIO_EXTRA_UNCORES 1
> +static struct intel_uncore_type *dmr_mmio_uncores[UNCORE_DMR_MMIO_EXTRA_UNCORES] = {
> + &dmr_uncore_iio_free_running,
> +};
> +
> int dmr_uncore_pci_init(void)
> {
> uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
> @@ -6937,11 +7040,16 @@ int dmr_uncore_pci_init(void)
> dmr_uncores);
> return 0;
> }
> +
> void dmr_uncore_mmio_init(void)
> {
> - uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL,
> - UNCORE_DMR_NUM_UNCORE_TYPES,
> - dmr_uncores);
> -}
> + uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
> + UNCORE_DMR_MMIO_EXTRA_UNCORES,
> + dmr_mmio_uncores,
> + UNCORE_DMR_NUM_UNCORE_TYPES,
> + dmr_uncores);
>
> + dmr_uncore_iio_free_running.num_boxes =
> + uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_DMR_ITC);
> +}
> /* end of DMR uncore support */
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 08/13] perf/x86/intel/uncore: Support IIO free-running counters on DMR
2026-01-04 2:31 ` Mi, Dapeng
@ 2026-02-06 0:26 ` Chun-Tse Shao
2026-02-06 5:51 ` Mi, Dapeng
0 siblings, 1 reply; 51+ messages in thread
From: Chun-Tse Shao @ 2026-02-06 0:26 UTC (permalink / raw)
To: Mi, Dapeng
Cc: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane, linux-kernel, linux-perf-users,
Xudong Hao, Falcon Thomas
On Sat, Jan 3, 2026 at 6:31 PM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
>
>
> On 1/1/2026 6:42 AM, Zide Chen wrote:
> > The free-running counters for IIO uncore blocks on Diamond Rapids are
> > similar to Sapphire Rapids IMC freecounters, with the following
> > differences:
> >
> > - The counters are MMIO based.
> > - Only a subset of IP blocks implement free-running counters:
> > HIOP0 (IP Base Addr: 2E7000h)
> > HIOP1 (IP Base Addr: 2EF000h)
> > HIOP3 (IP Base Addr: 2FF000h)
> > HIOP4 (IP Base Addr: 307000h)
> > - IMH2 (Secondary IMH) does not provide free-running counters.
> >
> > Signed-off-by: Zide Chen <zide.chen@intel.com>
> > ---
> > V2:
> > - Remove pr_warn() from dmr_uncore_freerunning_init_box().
> >
> > arch/x86/events/intel/uncore_snbep.c | 118 +++++++++++++++++++++++++--
> > 1 file changed, 113 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
> > index 09a3bdbd188a..28bcccf5cdfe 100644
> > --- a/arch/x86/events/intel/uncore_snbep.c
> > +++ b/arch/x86/events/intel/uncore_snbep.c
> > @@ -472,10 +472,14 @@
> > #define SPR_C0_MSR_PMON_BOX_FILTER0 0x200e
> >
> > /* DMR */
> > +#define DMR_IMH1_HIOP_MMIO_BASE 0x1ffff6ae7000
> > +#define DMR_HIOP_MMIO_SIZE 0x8000
> > #define DMR_CXLCM_EVENT_MASK_EXT 0xf
> > #define DMR_HAMVF_EVENT_MASK_EXT 0xffffffff
> > #define DMR_PCIE4_EVENT_MASK_EXT 0xffffff
> >
> > +#define UNCORE_DMR_ITC 0x30
> > +
> > #define DMR_IMC_PMON_FIXED_CTR 0x18
> > #define DMR_IMC_PMON_FIXED_CTL 0x10
> >
> > @@ -6442,7 +6446,11 @@ static int uncore_type_max_boxes(struct intel_uncore_type **types,
> > for (node = rb_first(type->boxes); node; node = rb_next(node)) {
> > unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
> >
> > - if (unit->id > max)
> > + /*
> > + * on DMR IMH2, the unit id starts from 0x8000,
> > + * and we don't need to count it.
> > + */
> > + if ((unit->id > max) && (unit->id < 0x8000))
> > max = unit->id;
> > }
> > return max + 1;
> > @@ -6930,6 +6938,101 @@ int dmr_uncore_cbb_units_ignore[] = {
> > UNCORE_IGNORE_END
> > };
> >
> > +static unsigned int dmr_iio_freerunning_box_offsets[] = {
> > + 0x0, 0x8000, 0x18000, 0x20000
> > +};
> > +
> > +static void dmr_uncore_freerunning_init_box(struct intel_uncore_box *box)
> > +{
> > + struct intel_uncore_type *type = box->pmu->type;
> > + u64 mmio_base;
> > +
> > + if (box->pmu->pmu_idx >= type->num_boxes)
> > + return;
> > +
> > + mmio_base = DMR_IMH1_HIOP_MMIO_BASE;
> > + mmio_base += dmr_iio_freerunning_box_offsets[box->pmu->pmu_idx];
> > +
> > + box->io_addr = ioremap(mmio_base, type->mmio_map_size);
> > + if (!box->io_addr)
> > + pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
> > +}
> > +
> > +static struct intel_uncore_ops dmr_uncore_freerunning_ops = {
> > + .init_box = dmr_uncore_freerunning_init_box,
> > + .exit_box = uncore_mmio_exit_box,
> > + .read_counter = uncore_mmio_read_counter,
> > + .hw_config = uncore_freerunning_hw_config,
> > +};
> > +
> > +enum perf_uncore_dmr_iio_freerunning_type_id {
> > + DMR_ITC_INB_DATA_BW,
> > + DMR_ITC_BW_IN,
> > + DMR_OTC_BW_OUT,
> > + DMR_OTC_CLOCK_TICKS,
> > +
> > + DMR_IIO_FREERUNNING_TYPE_MAX,
> > +};
> > +
> > +static struct freerunning_counters dmr_iio_freerunning[] = {
> > + [DMR_ITC_INB_DATA_BW] = { 0x4d40, 0x8, 0, 8, 48},
> > + [DMR_ITC_BW_IN] = { 0x6b00, 0x8, 0, 8, 48},
> > + [DMR_OTC_BW_OUT] = { 0x6b60, 0x8, 0, 8, 48},
> > + [DMR_OTC_CLOCK_TICKS] = { 0x6bb0, 0x8, 0, 1, 48},
> > +};
> > +
> > +static struct uncore_event_desc dmr_uncore_iio_freerunning_events[] = {
> > + /* ITC Free Running Data BW counter for inbound traffic */
> > + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port0, 0x10, "3.814697266e-6"),
Hi, it is probably a bit late but I think the third argument should be
a string. Because the macro already applies __stringify, the resulting
expansion is ""3.814697266e-6"", which eventually shows in sysfs
knobs. It would cause problems while Perf tries to parse the file.
Thanks,
CT
> > + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port1, 0x11, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port2, 0x12, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port3, 0x13, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port4, 0x14, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port5, 0x15, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port6, 0x16, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port7, 0x17, "3.814697266e-6"),
> > +
> > + /* ITC Free Running BW IN counters */
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port4, 0x24, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port5, 0x25, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port6, 0x26, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port7, 0x27, "3.814697266e-6"),
> > +
> > + /* ITC Free Running BW OUT counters */
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port0, 0x30, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port1, 0x31, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port2, 0x32, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port3, 0x33, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port4, 0x34, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port5, 0x35, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port6, 0x36, "3.814697266e-6"),
> > + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port7, 0x37, "3.814697266e-6"),
> > +
> > + /* Free Running Clock Counter */
> > + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x40"),
> > + { /* end: all zeroes */ },
> > +};
> > +
> > +static struct intel_uncore_type dmr_uncore_iio_free_running = {
> > + .name = "iio_free_running",
> > + .num_counters = 25,
> > + .mmio_map_size = DMR_HIOP_MMIO_SIZE,
> > + .num_freerunning_types = DMR_IIO_FREERUNNING_TYPE_MAX,
> > + .freerunning = dmr_iio_freerunning,
> > + .ops = &dmr_uncore_freerunning_ops,
> > + .event_descs = dmr_uncore_iio_freerunning_events,
> > + .format_group = &skx_uncore_iio_freerunning_format_group,
> > +};
> > +
> > +#define UNCORE_DMR_MMIO_EXTRA_UNCORES 1
> > +static struct intel_uncore_type *dmr_mmio_uncores[UNCORE_DMR_MMIO_EXTRA_UNCORES] = {
> > + &dmr_uncore_iio_free_running,
> > +};
> > +
> > int dmr_uncore_pci_init(void)
> > {
> > uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
> > @@ -6937,11 +7040,16 @@ int dmr_uncore_pci_init(void)
> > dmr_uncores);
> > return 0;
> > }
> > +
> > void dmr_uncore_mmio_init(void)
> > {
> > - uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL,
> > - UNCORE_DMR_NUM_UNCORE_TYPES,
> > - dmr_uncores);
> > -}
> > + uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
> > + UNCORE_DMR_MMIO_EXTRA_UNCORES,
> > + dmr_mmio_uncores,
> > + UNCORE_DMR_NUM_UNCORE_TYPES,
> > + dmr_uncores);
> >
> > + dmr_uncore_iio_free_running.num_boxes =
> > + uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_DMR_ITC);
> > +}
> > /* end of DMR uncore support */
>
> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>
>
>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 08/13] perf/x86/intel/uncore: Support IIO free-running counters on DMR
2026-02-06 0:26 ` Chun-Tse Shao
@ 2026-02-06 5:51 ` Mi, Dapeng
0 siblings, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-02-06 5:51 UTC (permalink / raw)
To: Chun-Tse Shao
Cc: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane, linux-kernel, linux-perf-users,
Xudong Hao, Falcon Thomas
On 2/6/2026 8:26 AM, Chun-Tse Shao wrote:
> On Sat, Jan 3, 2026 at 6:31 PM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
>>
>> On 1/1/2026 6:42 AM, Zide Chen wrote:
>>> The free-running counters for IIO uncore blocks on Diamond Rapids are
>>> similar to Sapphire Rapids IMC freecounters, with the following
>>> differences:
>>>
>>> - The counters are MMIO based.
>>> - Only a subset of IP blocks implement free-running counters:
>>> HIOP0 (IP Base Addr: 2E7000h)
>>> HIOP1 (IP Base Addr: 2EF000h)
>>> HIOP3 (IP Base Addr: 2FF000h)
>>> HIOP4 (IP Base Addr: 307000h)
>>> - IMH2 (Secondary IMH) does not provide free-running counters.
>>>
>>> Signed-off-by: Zide Chen <zide.chen@intel.com>
>>> ---
>>> V2:
>>> - Remove pr_warn() from dmr_uncore_freerunning_init_box().
>>>
>>> arch/x86/events/intel/uncore_snbep.c | 118 +++++++++++++++++++++++++--
>>> 1 file changed, 113 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
>>> index 09a3bdbd188a..28bcccf5cdfe 100644
>>> --- a/arch/x86/events/intel/uncore_snbep.c
>>> +++ b/arch/x86/events/intel/uncore_snbep.c
>>> @@ -472,10 +472,14 @@
>>> #define SPR_C0_MSR_PMON_BOX_FILTER0 0x200e
>>>
>>> /* DMR */
>>> +#define DMR_IMH1_HIOP_MMIO_BASE 0x1ffff6ae7000
>>> +#define DMR_HIOP_MMIO_SIZE 0x8000
>>> #define DMR_CXLCM_EVENT_MASK_EXT 0xf
>>> #define DMR_HAMVF_EVENT_MASK_EXT 0xffffffff
>>> #define DMR_PCIE4_EVENT_MASK_EXT 0xffffff
>>>
>>> +#define UNCORE_DMR_ITC 0x30
>>> +
>>> #define DMR_IMC_PMON_FIXED_CTR 0x18
>>> #define DMR_IMC_PMON_FIXED_CTL 0x10
>>>
>>> @@ -6442,7 +6446,11 @@ static int uncore_type_max_boxes(struct intel_uncore_type **types,
>>> for (node = rb_first(type->boxes); node; node = rb_next(node)) {
>>> unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
>>>
>>> - if (unit->id > max)
>>> + /*
>>> + * on DMR IMH2, the unit id starts from 0x8000,
>>> + * and we don't need to count it.
>>> + */
>>> + if ((unit->id > max) && (unit->id < 0x8000))
>>> max = unit->id;
>>> }
>>> return max + 1;
>>> @@ -6930,6 +6938,101 @@ int dmr_uncore_cbb_units_ignore[] = {
>>> UNCORE_IGNORE_END
>>> };
>>>
>>> +static unsigned int dmr_iio_freerunning_box_offsets[] = {
>>> + 0x0, 0x8000, 0x18000, 0x20000
>>> +};
>>> +
>>> +static void dmr_uncore_freerunning_init_box(struct intel_uncore_box *box)
>>> +{
>>> + struct intel_uncore_type *type = box->pmu->type;
>>> + u64 mmio_base;
>>> +
>>> + if (box->pmu->pmu_idx >= type->num_boxes)
>>> + return;
>>> +
>>> + mmio_base = DMR_IMH1_HIOP_MMIO_BASE;
>>> + mmio_base += dmr_iio_freerunning_box_offsets[box->pmu->pmu_idx];
>>> +
>>> + box->io_addr = ioremap(mmio_base, type->mmio_map_size);
>>> + if (!box->io_addr)
>>> + pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
>>> +}
>>> +
>>> +static struct intel_uncore_ops dmr_uncore_freerunning_ops = {
>>> + .init_box = dmr_uncore_freerunning_init_box,
>>> + .exit_box = uncore_mmio_exit_box,
>>> + .read_counter = uncore_mmio_read_counter,
>>> + .hw_config = uncore_freerunning_hw_config,
>>> +};
>>> +
>>> +enum perf_uncore_dmr_iio_freerunning_type_id {
>>> + DMR_ITC_INB_DATA_BW,
>>> + DMR_ITC_BW_IN,
>>> + DMR_OTC_BW_OUT,
>>> + DMR_OTC_CLOCK_TICKS,
>>> +
>>> + DMR_IIO_FREERUNNING_TYPE_MAX,
>>> +};
>>> +
>>> +static struct freerunning_counters dmr_iio_freerunning[] = {
>>> + [DMR_ITC_INB_DATA_BW] = { 0x4d40, 0x8, 0, 8, 48},
>>> + [DMR_ITC_BW_IN] = { 0x6b00, 0x8, 0, 8, 48},
>>> + [DMR_OTC_BW_OUT] = { 0x6b60, 0x8, 0, 8, 48},
>>> + [DMR_OTC_CLOCK_TICKS] = { 0x6bb0, 0x8, 0, 1, 48},
>>> +};
>>> +
>>> +static struct uncore_event_desc dmr_uncore_iio_freerunning_events[] = {
>>> + /* ITC Free Running Data BW counter for inbound traffic */
>>> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port0, 0x10, "3.814697266e-6"),
> Hi, it is probably a bit late but I think the third argument should be
> a string. Because the macro already applies __stringify, the resulting
> expansion is ""3.814697266e-6"", which eventually shows in sysfs
> knobs. It would cause problems while Perf tries to parse the file.
Good catch. This needs a fix. Thanks.
>
> Thanks,
> CT
>>> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port1, 0x11, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port2, 0x12, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port3, 0x13, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port4, 0x14, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port5, 0x15, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port6, 0x16, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(inb_data_port7, 0x17, "3.814697266e-6"),
>>> +
>>> + /* ITC Free Running BW IN counters */
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port4, 0x24, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port5, 0x25, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port6, 0x26, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_in_port7, 0x27, "3.814697266e-6"),
>>> +
>>> + /* ITC Free Running BW OUT counters */
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port0, 0x30, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port1, 0x31, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port2, 0x32, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port3, 0x33, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port4, 0x34, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port5, 0x35, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port6, 0x36, "3.814697266e-6"),
>>> + INTEL_UNCORE_FR_EVENT_DESC(bw_out_port7, 0x37, "3.814697266e-6"),
>>> +
>>> + /* Free Running Clock Counter */
>>> + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x40"),
>>> + { /* end: all zeroes */ },
>>> +};
>>> +
>>> +static struct intel_uncore_type dmr_uncore_iio_free_running = {
>>> + .name = "iio_free_running",
>>> + .num_counters = 25,
>>> + .mmio_map_size = DMR_HIOP_MMIO_SIZE,
>>> + .num_freerunning_types = DMR_IIO_FREERUNNING_TYPE_MAX,
>>> + .freerunning = dmr_iio_freerunning,
>>> + .ops = &dmr_uncore_freerunning_ops,
>>> + .event_descs = dmr_uncore_iio_freerunning_events,
>>> + .format_group = &skx_uncore_iio_freerunning_format_group,
>>> +};
>>> +
>>> +#define UNCORE_DMR_MMIO_EXTRA_UNCORES 1
>>> +static struct intel_uncore_type *dmr_mmio_uncores[UNCORE_DMR_MMIO_EXTRA_UNCORES] = {
>>> + &dmr_uncore_iio_free_running,
>>> +};
>>> +
>>> int dmr_uncore_pci_init(void)
>>> {
>>> uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
>>> @@ -6937,11 +7040,16 @@ int dmr_uncore_pci_init(void)
>>> dmr_uncores);
>>> return 0;
>>> }
>>> +
>>> void dmr_uncore_mmio_init(void)
>>> {
>>> - uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL,
>>> - UNCORE_DMR_NUM_UNCORE_TYPES,
>>> - dmr_uncores);
>>> -}
>>> + uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
>>> + UNCORE_DMR_MMIO_EXTRA_UNCORES,
>>> + dmr_mmio_uncores,
>>> + UNCORE_DMR_NUM_UNCORE_TYPES,
>>> + dmr_uncores);
>>>
>>> + dmr_uncore_iio_free_running.num_boxes =
>>> + uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_DMR_ITC);
>>> +}
>>> /* end of DMR uncore support */
>> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>>
>>
>>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [tip: perf/core] perf/x86/intel/uncore: Support IIO free-running counters on DMR
2025-12-31 22:42 ` [PATCH V2 08/13] perf/x86/intel/uncore: Support IIO free-running counters on DMR Zide Chen
2026-01-04 2:31 ` Mi, Dapeng
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: d8987048f6655b38453d00782a256179f082b79c
Gitweb: https://git.kernel.org/tip/d8987048f6655b38453d00782a256179f082b79c
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:25 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:25 +01:00
perf/x86/intel/uncore: Support IIO free-running counters on DMR
The free-running counters for IIO uncore blocks on Diamond Rapids are
similar to Sapphire Rapids IMC freecounters, with the following
differences:
- The counters are MMIO based.
- Only a subset of IP blocks implement free-running counters:
HIOP0 (IP Base Addr: 2E7000h)
HIOP1 (IP Base Addr: 2EF000h)
HIOP3 (IP Base Addr: 2FF000h)
HIOP4 (IP Base Addr: 307000h)
- IMH2 (Secondary IMH) does not provide free-running counters.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-9-zide.chen@intel.com
---
arch/x86/events/intel/uncore_snbep.c | 118 ++++++++++++++++++++++++--
1 file changed, 113 insertions(+), 5 deletions(-)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index cfb4ce3..cc8145e 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -472,10 +472,14 @@
#define SPR_C0_MSR_PMON_BOX_FILTER0 0x200e
/* DMR */
+#define DMR_IMH1_HIOP_MMIO_BASE 0x1ffff6ae7000
+#define DMR_HIOP_MMIO_SIZE 0x8000
#define DMR_CXLCM_EVENT_MASK_EXT 0xf
#define DMR_HAMVF_EVENT_MASK_EXT 0xffffffff
#define DMR_PCIE4_EVENT_MASK_EXT 0xffffff
+#define UNCORE_DMR_ITC 0x30
+
#define DMR_IMC_PMON_FIXED_CTR 0x18
#define DMR_IMC_PMON_FIXED_CTL 0x10
@@ -6442,7 +6446,11 @@ static int uncore_type_max_boxes(struct intel_uncore_type **types,
for (node = rb_first(type->boxes); node; node = rb_next(node)) {
unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
- if (unit->id > max)
+ /*
+ * on DMR IMH2, the unit id starts from 0x8000,
+ * and we don't need to count it.
+ */
+ if ((unit->id > max) && (unit->id < 0x8000))
max = unit->id;
}
return max + 1;
@@ -6930,6 +6938,101 @@ int dmr_uncore_cbb_units_ignore[] = {
UNCORE_IGNORE_END
};
+static unsigned int dmr_iio_freerunning_box_offsets[] = {
+ 0x0, 0x8000, 0x18000, 0x20000
+};
+
+static void dmr_uncore_freerunning_init_box(struct intel_uncore_box *box)
+{
+ struct intel_uncore_type *type = box->pmu->type;
+ u64 mmio_base;
+
+ if (box->pmu->pmu_idx >= type->num_boxes)
+ return;
+
+ mmio_base = DMR_IMH1_HIOP_MMIO_BASE;
+ mmio_base += dmr_iio_freerunning_box_offsets[box->pmu->pmu_idx];
+
+ box->io_addr = ioremap(mmio_base, type->mmio_map_size);
+ if (!box->io_addr)
+ pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
+}
+
+static struct intel_uncore_ops dmr_uncore_freerunning_ops = {
+ .init_box = dmr_uncore_freerunning_init_box,
+ .exit_box = uncore_mmio_exit_box,
+ .read_counter = uncore_mmio_read_counter,
+ .hw_config = uncore_freerunning_hw_config,
+};
+
+enum perf_uncore_dmr_iio_freerunning_type_id {
+ DMR_ITC_INB_DATA_BW,
+ DMR_ITC_BW_IN,
+ DMR_OTC_BW_OUT,
+ DMR_OTC_CLOCK_TICKS,
+
+ DMR_IIO_FREERUNNING_TYPE_MAX,
+};
+
+static struct freerunning_counters dmr_iio_freerunning[] = {
+ [DMR_ITC_INB_DATA_BW] = { 0x4d40, 0x8, 0, 8, 48},
+ [DMR_ITC_BW_IN] = { 0x6b00, 0x8, 0, 8, 48},
+ [DMR_OTC_BW_OUT] = { 0x6b60, 0x8, 0, 8, 48},
+ [DMR_OTC_CLOCK_TICKS] = { 0x6bb0, 0x8, 0, 1, 48},
+};
+
+static struct uncore_event_desc dmr_uncore_iio_freerunning_events[] = {
+ /* ITC Free Running Data BW counter for inbound traffic */
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port0, 0x10, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port1, 0x11, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port2, 0x12, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port3, 0x13, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port4, 0x14, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port5, 0x15, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port6, 0x16, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(inb_data_port7, 0x17, "3.814697266e-6"),
+
+ /* ITC Free Running BW IN counters */
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port0, 0x20, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port1, 0x21, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port2, 0x22, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port3, 0x23, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port4, 0x24, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port5, 0x25, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port6, 0x26, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_in_port7, 0x27, "3.814697266e-6"),
+
+ /* ITC Free Running BW OUT counters */
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port0, 0x30, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port1, 0x31, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port2, 0x32, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port3, 0x33, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port4, 0x34, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port5, 0x35, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port6, 0x36, "3.814697266e-6"),
+ INTEL_UNCORE_FR_EVENT_DESC(bw_out_port7, 0x37, "3.814697266e-6"),
+
+ /* Free Running Clock Counter */
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x40"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_type dmr_uncore_iio_free_running = {
+ .name = "iio_free_running",
+ .num_counters = 25,
+ .mmio_map_size = DMR_HIOP_MMIO_SIZE,
+ .num_freerunning_types = DMR_IIO_FREERUNNING_TYPE_MAX,
+ .freerunning = dmr_iio_freerunning,
+ .ops = &dmr_uncore_freerunning_ops,
+ .event_descs = dmr_uncore_iio_freerunning_events,
+ .format_group = &skx_uncore_iio_freerunning_format_group,
+};
+
+#define UNCORE_DMR_MMIO_EXTRA_UNCORES 1
+static struct intel_uncore_type *dmr_mmio_uncores[UNCORE_DMR_MMIO_EXTRA_UNCORES] = {
+ &dmr_uncore_iio_free_running,
+};
+
int dmr_uncore_pci_init(void)
{
uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
@@ -6937,11 +7040,16 @@ int dmr_uncore_pci_init(void)
dmr_uncores);
return 0;
}
+
void dmr_uncore_mmio_init(void)
{
- uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL,
- UNCORE_DMR_NUM_UNCORE_TYPES,
- dmr_uncores);
-}
+ uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO,
+ UNCORE_DMR_MMIO_EXTRA_UNCORES,
+ dmr_mmio_uncores,
+ UNCORE_DMR_NUM_UNCORE_TYPES,
+ dmr_uncores);
+ dmr_uncore_iio_free_running.num_boxes =
+ uncore_type_max_boxes(uncore_mmio_uncores, UNCORE_DMR_ITC);
+}
/* end of DMR uncore support */
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 09/13] perf/x86/intel/uncore: Support uncore constraint ranges
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (7 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 08/13] perf/x86/intel/uncore: Support IIO free-running counters on DMR Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 2:36 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 10/13] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily Zide Chen
` (4 subsequent siblings)
13 siblings, 2 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
Add UNCORE_EVENT_CONSTRAINT_RANGE macro for uncore constraints,
similar to INTEL_EVENT_CONSTRAINT_RANGE, to reduce duplication when
defining consecutive uncore event constraints.
No functional change intended.
Suggested-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2: new patch
arch/x86/events/intel/uncore.c | 2 +-
arch/x86/events/intel/uncore.h | 2 +
arch/x86/events/intel/uncore_snbep.c | 183 ++++++---------------------
3 files changed, 44 insertions(+), 143 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 080b6870a88d..54b3c1e3af32 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -436,7 +436,7 @@ uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *eve
if (type->constraints) {
for_each_event_constraint(c, type->constraints) {
- if ((event->hw.config & c->cmask) == c->code)
+ if (constraint_match(c, event->hw.config))
return c;
}
}
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 55e3aebf4b5e..564cb26c4468 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -33,6 +33,8 @@
#define UNCORE_EXTRA_PCI_DEV_MAX 4
#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
+#define UNCORE_EVENT_CONSTRAINT_RANGE(c, e, n) \
+ EVENT_CONSTRAINT_RANGE(c, e, n, 0xff)
#define UNCORE_IGNORE_END -1
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 28bcccf5cdfe..fac2be780276 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -836,76 +836,37 @@ static struct intel_uncore_ops snbep_uncore_pci_ops = {
static struct event_constraint snbep_uncore_cbox_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x04, 0x5, 0x3),
UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x12, 0x13, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1b, 0x1e, 0xc),
UNCORE_EVENT_CONSTRAINT(0x1f, 0xe),
UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x31, 0x35, 0x3),
UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x37, 0x39, 0x3),
UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
EVENT_CONSTRAINT_END
};
static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x24, 0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x32, 0x34, 0x3),
EVENT_CONSTRAINT_END
};
static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x12, 0x3),
UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x20, 0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3034,24 +2995,15 @@ static struct intel_uncore_type hswep_uncore_qpi = {
};
static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x23, 0x25, 0x1),
UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x2b, 0x2d, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x32, 0x35, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3066,38 +3018,17 @@ static struct intel_uncore_type hswep_uncore_r2pcie = {
static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x7, 0x0a, 0x7),
UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x12, 0x3),
UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x14, 0x15, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1f, 0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x25, 0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2f, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x31, 0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3371,8 +3302,7 @@ static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2d, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3387,35 +3317,18 @@ static struct intel_uncore_type bdx_uncore_r2pcie = {
static struct event_constraint bdx_uncore_r3qpi_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x01, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x07, 0x0a, 0x7),
UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x14, 0x15, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1f, 0x23, 0x3),
UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2f, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x33, 0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3722,8 +3635,7 @@ static struct event_constraint skx_uncore_iio_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x95, 0xc),
UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
- UNCORE_EVENT_CONSTRAINT(0xd4, 0xc),
- UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0xd4, 0xd5, 0xc),
EVENT_CONSTRAINT_END
};
@@ -4479,14 +4391,9 @@ static struct intel_uncore_type skx_uncore_m2pcie = {
};
static struct event_constraint skx_uncore_m3upi_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1d, 0x1e, 0x1),
UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x51, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x52, 0x7),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x4e, 0x52, 0x7),
EVENT_CONSTRAINT_END
};
@@ -5652,14 +5559,9 @@ static struct intel_uncore_type icx_uncore_upi = {
};
static struct event_constraint icx_uncore_m3upi_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x1c, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1c, 0x1f, 0x1),
UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x4e, 0x50, 0x7),
EVENT_CONSTRAINT_END
};
@@ -6142,10 +6044,7 @@ static struct intel_uncore_ops spr_uncore_mmio_offs8_ops = {
static struct event_constraint spr_uncore_cxlcm_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x02, 0x0f),
UNCORE_EVENT_CONSTRAINT(0x05, 0x0f),
- UNCORE_EVENT_CONSTRAINT(0x40, 0xf0),
- UNCORE_EVENT_CONSTRAINT(0x41, 0xf0),
- UNCORE_EVENT_CONSTRAINT(0x42, 0xf0),
- UNCORE_EVENT_CONSTRAINT(0x43, 0xf0),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x40, 0x43, 0xf0),
UNCORE_EVENT_CONSTRAINT(0x4b, 0xf0),
UNCORE_EVENT_CONSTRAINT(0x52, 0xf0),
EVENT_CONSTRAINT_END
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 09/13] perf/x86/intel/uncore: Support uncore constraint ranges
2025-12-31 22:42 ` [PATCH V2 09/13] perf/x86/intel/uncore: Support uncore constraint ranges Zide Chen
@ 2026-01-04 2:36 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:36 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> Add UNCORE_EVENT_CONSTRAINT_RANGE macro for uncore constraints,
> similar to INTEL_EVENT_CONSTRAINT_RANGE, to reduce duplication when
> defining consecutive uncore event constraints.
>
> No functional change intended.
>
> Suggested-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2: new patch
>
> arch/x86/events/intel/uncore.c | 2 +-
> arch/x86/events/intel/uncore.h | 2 +
> arch/x86/events/intel/uncore_snbep.c | 183 ++++++---------------------
> 3 files changed, 44 insertions(+), 143 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 080b6870a88d..54b3c1e3af32 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -436,7 +436,7 @@ uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *eve
>
> if (type->constraints) {
> for_each_event_constraint(c, type->constraints) {
> - if ((event->hw.config & c->cmask) == c->code)
> + if (constraint_match(c, event->hw.config))
> return c;
> }
> }
> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
> index 55e3aebf4b5e..564cb26c4468 100644
> --- a/arch/x86/events/intel/uncore.h
> +++ b/arch/x86/events/intel/uncore.h
> @@ -33,6 +33,8 @@
> #define UNCORE_EXTRA_PCI_DEV_MAX 4
>
> #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
> +#define UNCORE_EVENT_CONSTRAINT_RANGE(c, e, n) \
> + EVENT_CONSTRAINT_RANGE(c, e, n, 0xff)
>
> #define UNCORE_IGNORE_END -1
>
> diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
> index 28bcccf5cdfe..fac2be780276 100644
> --- a/arch/x86/events/intel/uncore_snbep.c
> +++ b/arch/x86/events/intel/uncore_snbep.c
> @@ -836,76 +836,37 @@ static struct intel_uncore_ops snbep_uncore_pci_ops = {
> static struct event_constraint snbep_uncore_cbox_constraints[] = {
> UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
> UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x04, 0x5, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
> - UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
> - UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
> - UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x12, 0x13, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x1b, 0x1e, 0xc),
> UNCORE_EVENT_CONSTRAINT(0x1f, 0xe),
> UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x31, 0x35, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x37, 0x39, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
> EVENT_CONSTRAINT_END
> };
>
> static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
> - UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
> UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x24, 0x26, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x32, 0x34, 0x3),
> EVENT_CONSTRAINT_END
> };
>
> static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
> - UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x12, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x20, 0x26, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x34, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
> EVENT_CONSTRAINT_END
> };
>
> @@ -3034,24 +2995,15 @@ static struct intel_uncore_type hswep_uncore_qpi = {
> };
>
> static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
> - UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x23, 0x25, 0x1),
> UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x2b, 0x2d, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x32, 0x35, 0x3),
> EVENT_CONSTRAINT_END
> };
>
> @@ -3066,38 +3018,17 @@ static struct intel_uncore_type hswep_uncore_r2pcie = {
>
> static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
> UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x7, 0x0a, 0x7),
> UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x12, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x14, 0x15, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x1f, 0x23, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x25, 0x26, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2f, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x31, 0x34, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
> EVENT_CONSTRAINT_END
> };
>
> @@ -3371,8 +3302,7 @@ static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
> UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
> UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2d, 0x3),
> EVENT_CONSTRAINT_END
> };
>
> @@ -3387,35 +3317,18 @@ static struct intel_uncore_type bdx_uncore_r2pcie = {
>
> static struct event_constraint bdx_uncore_r3qpi_constraints[] = {
> UNCORE_EVENT_CONSTRAINT(0x01, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x07, 0x0a, 0x7),
> UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x14, 0x15, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x1f, 0x23, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
> UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
> - UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2f, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x33, 0x34, 0x3),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
> EVENT_CONSTRAINT_END
> };
>
> @@ -3722,8 +3635,7 @@ static struct event_constraint skx_uncore_iio_constraints[] = {
> UNCORE_EVENT_CONSTRAINT(0x95, 0xc),
> UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
> UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
> - UNCORE_EVENT_CONSTRAINT(0xd4, 0xc),
> - UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0xd4, 0xd5, 0xc),
> EVENT_CONSTRAINT_END
> };
>
> @@ -4479,14 +4391,9 @@ static struct intel_uncore_type skx_uncore_m2pcie = {
> };
>
> static struct event_constraint skx_uncore_m3upi_constraints[] = {
> - UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x1d, 0x1e, 0x1),
> UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x51, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x52, 0x7),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x4e, 0x52, 0x7),
> EVENT_CONSTRAINT_END
> };
>
> @@ -5652,14 +5559,9 @@ static struct intel_uncore_type icx_uncore_upi = {
> };
>
> static struct event_constraint icx_uncore_m3upi_constraints[] = {
> - UNCORE_EVENT_CONSTRAINT(0x1c, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
> - UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x1c, 0x1f, 0x1),
> UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
> - UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x4e, 0x50, 0x7),
> EVENT_CONSTRAINT_END
> };
>
> @@ -6142,10 +6044,7 @@ static struct intel_uncore_ops spr_uncore_mmio_offs8_ops = {
> static struct event_constraint spr_uncore_cxlcm_constraints[] = {
> UNCORE_EVENT_CONSTRAINT(0x02, 0x0f),
> UNCORE_EVENT_CONSTRAINT(0x05, 0x0f),
> - UNCORE_EVENT_CONSTRAINT(0x40, 0xf0),
> - UNCORE_EVENT_CONSTRAINT(0x41, 0xf0),
> - UNCORE_EVENT_CONSTRAINT(0x42, 0xf0),
> - UNCORE_EVENT_CONSTRAINT(0x43, 0xf0),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x40, 0x43, 0xf0),
> UNCORE_EVENT_CONSTRAINT(0x4b, 0xf0),
> UNCORE_EVENT_CONSTRAINT(0x52, 0xf0),
> EVENT_CONSTRAINT_END
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Support uncore constraint ranges
2025-12-31 22:42 ` [PATCH V2 09/13] perf/x86/intel/uncore: Support uncore constraint ranges Zide Chen
2026-01-04 2:36 ` Mi, Dapeng
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Dapeng Mi, Zide Chen, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: aacb0718fddfe7060576c82e47bbda559c2f2d0d
Gitweb: https://git.kernel.org/tip/aacb0718fddfe7060576c82e47bbda559c2f2d0d
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:26 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:25 +01:00
perf/x86/intel/uncore: Support uncore constraint ranges
Add UNCORE_EVENT_CONSTRAINT_RANGE macro for uncore constraints,
similar to INTEL_EVENT_CONSTRAINT_RANGE, to reduce duplication when
defining consecutive uncore event constraints.
No functional change intended.
Suggested-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-10-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 2 +-
arch/x86/events/intel/uncore.h | 2 +-
arch/x86/events/intel/uncore_snbep.c | 183 +++++---------------------
3 files changed, 44 insertions(+), 143 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 25a678b..19ff8db 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -436,7 +436,7 @@ uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *eve
if (type->constraints) {
for_each_event_constraint(c, type->constraints) {
- if ((event->hw.config & c->cmask) == c->code)
+ if (constraint_match(c, event->hw.config))
return c;
}
}
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 55e3aeb..564cb26 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -33,6 +33,8 @@
#define UNCORE_EXTRA_PCI_DEV_MAX 4
#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
+#define UNCORE_EVENT_CONSTRAINT_RANGE(c, e, n) \
+ EVENT_CONSTRAINT_RANGE(c, e, n, 0xff)
#define UNCORE_IGNORE_END -1
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index cc8145e..eaeb4e9 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -836,76 +836,37 @@ static struct intel_uncore_ops snbep_uncore_pci_ops = {
static struct event_constraint snbep_uncore_cbox_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x04, 0x5, 0x3),
UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
UNCORE_EVENT_CONSTRAINT(0x09, 0x3),
UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
- UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x12, 0x13, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1b, 0x1e, 0xc),
UNCORE_EVENT_CONSTRAINT(0x1f, 0xe),
UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x31, 0x35, 0x3),
UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x37, 0x39, 0x3),
UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
EVENT_CONSTRAINT_END
};
static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x24, 0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x32, 0x34, 0x3),
EVENT_CONSTRAINT_END
};
static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x12, 0x3),
UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2a, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x20, 0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3034,24 +2995,15 @@ static struct intel_uncore_type hswep_uncore_qpi = {
};
static struct event_constraint hswep_uncore_r2pcie_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x24, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x23, 0x25, 0x1),
UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
UNCORE_EVENT_CONSTRAINT(0x27, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
UNCORE_EVENT_CONSTRAINT(0x2a, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x2b, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x2b, 0x2d, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x32, 0x35, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3066,38 +3018,17 @@ static struct intel_uncore_type hswep_uncore_r2pcie = {
static struct event_constraint hswep_uncore_r3qpi_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x01, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x7, 0x0a, 0x7),
UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x12, 0x3),
UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x14, 0x15, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1f, 0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x25, 0x26, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2f, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x31, 0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3371,8 +3302,7 @@ static struct event_constraint bdx_uncore_r2pcie_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2d, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3387,35 +3317,18 @@ static struct intel_uncore_type bdx_uncore_r2pcie = {
static struct event_constraint bdx_uncore_r3qpi_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x01, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x07, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x08, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x09, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x0a, 0x7),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x07, 0x0a, 0x7),
UNCORE_EVENT_CONSTRAINT(0x0e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x10, 0x11, 0x3),
UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x14, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x15, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x1f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x14, 0x15, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1f, 0x23, 0x3),
UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x28, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x29, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2c, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2d, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2e, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x2f, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
- UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x28, 0x29, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x2c, 0x2f, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x33, 0x34, 0x3),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x36, 0x39, 0x3),
EVENT_CONSTRAINT_END
};
@@ -3722,8 +3635,7 @@ static struct event_constraint skx_uncore_iio_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x95, 0xc),
UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
- UNCORE_EVENT_CONSTRAINT(0xd4, 0xc),
- UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0xd4, 0xd5, 0xc),
EVENT_CONSTRAINT_END
};
@@ -4479,14 +4391,9 @@ static struct intel_uncore_type skx_uncore_m2pcie = {
};
static struct event_constraint skx_uncore_m3upi_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1d, 0x1e, 0x1),
UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x51, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x52, 0x7),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x4e, 0x52, 0x7),
EVENT_CONSTRAINT_END
};
@@ -5652,14 +5559,9 @@ static struct intel_uncore_type icx_uncore_upi = {
};
static struct event_constraint icx_uncore_m3upi_constraints[] = {
- UNCORE_EVENT_CONSTRAINT(0x1c, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x1d, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x1e, 0x1),
- UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1c, 0x1f, 0x1),
UNCORE_EVENT_CONSTRAINT(0x40, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x4e, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x4f, 0x7),
- UNCORE_EVENT_CONSTRAINT(0x50, 0x7),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x4e, 0x50, 0x7),
EVENT_CONSTRAINT_END
};
@@ -6142,10 +6044,7 @@ static struct intel_uncore_ops spr_uncore_mmio_offs8_ops = {
static struct event_constraint spr_uncore_cxlcm_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x02, 0x0f),
UNCORE_EVENT_CONSTRAINT(0x05, 0x0f),
- UNCORE_EVENT_CONSTRAINT(0x40, 0xf0),
- UNCORE_EVENT_CONSTRAINT(0x41, 0xf0),
- UNCORE_EVENT_CONSTRAINT(0x42, 0xf0),
- UNCORE_EVENT_CONSTRAINT(0x43, 0xf0),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x40, 0x43, 0xf0),
UNCORE_EVENT_CONSTRAINT(0x4b, 0xf0),
UNCORE_EVENT_CONSTRAINT(0x52, 0xf0),
EVENT_CONSTRAINT_END
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 10/13] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (8 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 09/13] perf/x86/intel/uncore: Support uncore constraint ranges Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 2:41 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2025-12-31 22:42 ` [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix Zide Chen
` (3 subsequent siblings)
13 siblings, 2 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
Update event constraints base on the latest DMR uncore event list.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2:
- make use of the new UNCORE_EVENT_CONSTRAINT_RANGE
arch/x86/events/intel/uncore_snbep.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index fac2be780276..3f96fcc8562b 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -6660,10 +6660,19 @@ static const struct attribute_group dmr_cxlcm_uncore_format_group = {
.attrs = dmr_cxlcm_uncore_formats_attr,
};
+static struct event_constraint dmr_uncore_cxlcm_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1, 0x24, 0x0f),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x41, 0x41, 0xf0),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x50, 0x5e, 0xf0),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x60, 0x61, 0xf0),
+ EVENT_CONSTRAINT_END
+};
+
static struct intel_uncore_type dmr_uncore_cxlcm = {
.name = "cxlcm",
.event_mask = GENERIC_PMON_RAW_EVENT_MASK,
.event_mask_ext = DMR_CXLCM_EVENT_MASK_EXT,
+ .constraints = dmr_uncore_cxlcm_constraints,
.format_group = &dmr_cxlcm_uncore_format_group,
.attr_update = uncore_alias_groups,
};
@@ -6675,9 +6684,20 @@ static struct intel_uncore_type dmr_uncore_hamvf = {
.attr_update = uncore_alias_groups,
};
+static struct event_constraint dmr_uncore_cbo_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x19, 0x1a, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x21, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
static struct intel_uncore_type dmr_uncore_cbo = {
.name = "cbo",
.event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .constraints = dmr_uncore_cbo_constraints,
.format_group = &dmr_sca_uncore_format_group,
.attr_update = uncore_alias_groups,
};
@@ -6711,9 +6731,16 @@ static struct intel_uncore_type dmr_uncore_dda = {
.attr_update = uncore_alias_groups,
};
+static struct event_constraint dmr_uncore_sbo_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x1f, 0x01),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x01),
+ EVENT_CONSTRAINT_END
+};
+
static struct intel_uncore_type dmr_uncore_sbo = {
.name = "sbo",
.event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .constraints = dmr_uncore_sbo_constraints,
.format_group = &dmr_sca_uncore_format_group,
.attr_update = uncore_alias_groups,
};
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 10/13] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily
2025-12-31 22:42 ` [PATCH V2 10/13] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily Zide Chen
@ 2026-01-04 2:41 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:41 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> Update event constraints base on the latest DMR uncore event list.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2:
> - make use of the new UNCORE_EVENT_CONSTRAINT_RANGE
>
> arch/x86/events/intel/uncore_snbep.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
> index fac2be780276..3f96fcc8562b 100644
> --- a/arch/x86/events/intel/uncore_snbep.c
> +++ b/arch/x86/events/intel/uncore_snbep.c
> @@ -6660,10 +6660,19 @@ static const struct attribute_group dmr_cxlcm_uncore_format_group = {
> .attrs = dmr_cxlcm_uncore_formats_attr,
> };
>
> +static struct event_constraint dmr_uncore_cxlcm_constraints[] = {
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x1, 0x24, 0x0f),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x41, 0x41, 0xf0),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x50, 0x5e, 0xf0),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x60, 0x61, 0xf0),
> + EVENT_CONSTRAINT_END
> +};
> +
> static struct intel_uncore_type dmr_uncore_cxlcm = {
> .name = "cxlcm",
> .event_mask = GENERIC_PMON_RAW_EVENT_MASK,
> .event_mask_ext = DMR_CXLCM_EVENT_MASK_EXT,
> + .constraints = dmr_uncore_cxlcm_constraints,
> .format_group = &dmr_cxlcm_uncore_format_group,
> .attr_update = uncore_alias_groups,
> };
> @@ -6675,9 +6684,20 @@ static struct intel_uncore_type dmr_uncore_hamvf = {
> .attr_update = uncore_alias_groups,
> };
>
> +static struct event_constraint dmr_uncore_cbo_constraints[] = {
> + UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
> + UNCORE_EVENT_CONSTRAINT_RANGE(0x19, 0x1a, 0x1),
> + UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
> + UNCORE_EVENT_CONSTRAINT(0x21, 0x1),
> + UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
> + UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
> + EVENT_CONSTRAINT_END
> +};
> +
> static struct intel_uncore_type dmr_uncore_cbo = {
> .name = "cbo",
> .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
> + .constraints = dmr_uncore_cbo_constraints,
> .format_group = &dmr_sca_uncore_format_group,
> .attr_update = uncore_alias_groups,
> };
> @@ -6711,9 +6731,16 @@ static struct intel_uncore_type dmr_uncore_dda = {
> .attr_update = uncore_alias_groups,
> };
>
> +static struct event_constraint dmr_uncore_sbo_constraints[] = {
> + UNCORE_EVENT_CONSTRAINT(0x1f, 0x01),
> + UNCORE_EVENT_CONSTRAINT(0x25, 0x01),
> + EVENT_CONSTRAINT_END
> +};
> +
> static struct intel_uncore_type dmr_uncore_sbo = {
> .name = "sbo",
> .event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
> + .constraints = dmr_uncore_sbo_constraints,
> .format_group = &dmr_sca_uncore_format_group,
> .attr_update = uncore_alias_groups,
> };
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily
2025-12-31 22:42 ` [PATCH V2 10/13] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily Zide Chen
2026-01-04 2:41 ` Mi, Dapeng
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 171b5292a82d04e6692f1b19573d15753f21e7fd
Gitweb: https://git.kernel.org/tip/171b5292a82d04e6692f1b19573d15753f21e7fd
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:27 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:25 +01:00
perf/x86/intel/uncore: Update DMR uncore constraints preliminarily
Update event constraints base on the latest DMR uncore event list.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-11-zide.chen@intel.com
---
arch/x86/events/intel/uncore_snbep.c | 27 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index eaeb4e9..7ca0429 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -6660,10 +6660,19 @@ static const struct attribute_group dmr_cxlcm_uncore_format_group = {
.attrs = dmr_cxlcm_uncore_formats_attr,
};
+static struct event_constraint dmr_uncore_cxlcm_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x1, 0x24, 0x0f),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x41, 0x41, 0xf0),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x50, 0x5e, 0xf0),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x60, 0x61, 0xf0),
+ EVENT_CONSTRAINT_END
+};
+
static struct intel_uncore_type dmr_uncore_cxlcm = {
.name = "cxlcm",
.event_mask = GENERIC_PMON_RAW_EVENT_MASK,
.event_mask_ext = DMR_CXLCM_EVENT_MASK_EXT,
+ .constraints = dmr_uncore_cxlcm_constraints,
.format_group = &dmr_cxlcm_uncore_format_group,
.attr_update = uncore_alias_groups,
};
@@ -6675,9 +6684,20 @@ static struct intel_uncore_type dmr_uncore_hamvf = {
.attr_update = uncore_alias_groups,
};
+static struct event_constraint dmr_uncore_cbo_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
+ UNCORE_EVENT_CONSTRAINT_RANGE(0x19, 0x1a, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x1f, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x21, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x1),
+ UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
+ EVENT_CONSTRAINT_END
+};
+
static struct intel_uncore_type dmr_uncore_cbo = {
.name = "cbo",
.event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .constraints = dmr_uncore_cbo_constraints,
.format_group = &dmr_sca_uncore_format_group,
.attr_update = uncore_alias_groups,
};
@@ -6711,9 +6731,16 @@ static struct intel_uncore_type dmr_uncore_dda = {
.attr_update = uncore_alias_groups,
};
+static struct event_constraint dmr_uncore_sbo_constraints[] = {
+ UNCORE_EVENT_CONSTRAINT(0x1f, 0x01),
+ UNCORE_EVENT_CONSTRAINT(0x25, 0x01),
+ EVENT_CONSTRAINT_END
+};
+
static struct intel_uncore_type dmr_uncore_sbo = {
.name = "sbo",
.event_mask_ext = DMR_HAMVF_EVENT_MASK_EXT,
+ .constraints = dmr_uncore_sbo_constraints,
.format_group = &dmr_sca_uncore_format_group,
.attr_update = uncore_alias_groups,
};
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (9 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 10/13] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2026-01-21 7:18 ` [PATCH V2 11/13] " Ian Rogers
2025-12-31 22:42 ` [PATCH V2 12/13] perf/x86/intel/uncore: Add missing PMON units for Panther Lake Zide Chen
` (2 subsequent siblings)
13 siblings, 2 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
Diamond Rapids introduces two types of PCIe related uncore PMUs:
"uncore_pcie4_*" and "uncore_pcie6_*".
To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
and collect events from both PMU types, slightly relax the wildcard
matching logic in perf_pmu__match_wildcard().
This change allows a wildcard such as "pcie" to match PMU names that
include a numeric suffix, such as "pcie4_*" and "pcie6_*".
Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
tools/perf/util/pmu.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 956ea273c2c7..01a21b6aa031 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
{
const char *p, *suffix;
bool has_hex = false;
+ bool has_underscore = false;
size_t tok_len = strlen(tok);
/* Check start of pmu_name for equality. */
@@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
if (*p == 0)
return true;
- if (*p == '_') {
- ++p;
- ++suffix;
- }
-
- /* Ensure we end in a number */
+ /* Ensure we end in a number or a mix of number and "_". */
while (1) {
+ if (!has_underscore && (*p == '_')) {
+ has_underscore = true;
+ ++p;
+ ++suffix;
+ }
+
if (!isxdigit(*p))
return false;
if (!has_hex)
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* [tip: perf/core] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2025-12-31 22:42 ` [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix Zide Chen
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
2026-01-21 7:18 ` [PATCH V2 11/13] " Ian Rogers
1 sibling, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Dapeng Mi, Zide Chen, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 2246c24426fbc1069cb2a47e0624ccffe5f2627b
Gitweb: https://git.kernel.org/tip/2246c24426fbc1069cb2a47e0624ccffe5f2627b
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:28 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:26 +01:00
perf pmu: Relax uncore wildcard matching to allow numeric suffix
Diamond Rapids introduces two types of PCIe related uncore PMUs:
"uncore_pcie4_*" and "uncore_pcie6_*".
To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
and collect events from both PMU types, slightly relax the wildcard
matching logic in perf_pmu__match_wildcard().
This change allows a wildcard such as "pcie" to match PMU names that
include a numeric suffix, such as "pcie4_*" and "pcie6_*".
Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-12-zide.chen@intel.com
---
tools/perf/util/pmu.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 956ea27..01a21b6 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
{
const char *p, *suffix;
bool has_hex = false;
+ bool has_underscore = false;
size_t tok_len = strlen(tok);
/* Check start of pmu_name for equality. */
@@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
if (*p == 0)
return true;
- if (*p == '_') {
- ++p;
- ++suffix;
- }
-
- /* Ensure we end in a number */
+ /* Ensure we end in a number or a mix of number and "_". */
while (1) {
+ if (!has_underscore && (*p == '_')) {
+ has_underscore = true;
+ ++p;
+ ++suffix;
+ }
+
if (!isxdigit(*p))
return false;
if (!has_hex)
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2025-12-31 22:42 ` [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix Zide Chen
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
@ 2026-01-21 7:18 ` Ian Rogers
2026-01-21 8:02 ` Mi, Dapeng
1 sibling, 1 reply; 51+ messages in thread
From: Ian Rogers @ 2026-01-21 7:18 UTC (permalink / raw)
To: Zide Chen
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Adrian Hunter, Alexander Shishkin, Andi Kleen,
Eranian Stephane, linux-kernel, linux-perf-users, Dapeng Mi,
Xudong Hao, Falcon Thomas
On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
>
> Diamond Rapids introduces two types of PCIe related uncore PMUs:
> "uncore_pcie4_*" and "uncore_pcie6_*".
>
> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
> and collect events from both PMU types, slightly relax the wildcard
> matching logic in perf_pmu__match_wildcard().
>
> This change allows a wildcard such as "pcie" to match PMU names that
> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
>
> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
Can we not merge this. I'd missed a perf tool patch as it was hiding
in a bunch of kernel uncore updates. At the very least if wildcard
conventions are updated then the corresponding documentation needs
updating:
Documentation/ABI/testing/sysfs-bus-event_source-devices
Thanks,
Ian
> ---
> tools/perf/util/pmu.c | 14 ++++++++------
> 1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> index 956ea273c2c7..01a21b6aa031 100644
> --- a/tools/perf/util/pmu.c
> +++ b/tools/perf/util/pmu.c
> @@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> {
> const char *p, *suffix;
> bool has_hex = false;
> + bool has_underscore = false;
> size_t tok_len = strlen(tok);
>
> /* Check start of pmu_name for equality. */
> @@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> if (*p == 0)
> return true;
>
> - if (*p == '_') {
> - ++p;
> - ++suffix;
> - }
> -
> - /* Ensure we end in a number */
> + /* Ensure we end in a number or a mix of number and "_". */
> while (1) {
> + if (!has_underscore && (*p == '_')) {
> + has_underscore = true;
> + ++p;
> + ++suffix;
> + }
> +
> if (!isxdigit(*p))
> return false;
> if (!has_hex)
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2026-01-21 7:18 ` [PATCH V2 11/13] " Ian Rogers
@ 2026-01-21 8:02 ` Mi, Dapeng
2026-01-21 14:33 ` Ian Rogers
0 siblings, 1 reply; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-21 8:02 UTC (permalink / raw)
To: Ian Rogers, Zide Chen
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Adrian Hunter, Alexander Shishkin, Andi Kleen,
Eranian Stephane, linux-kernel, linux-perf-users, Xudong Hao,
Falcon Thomas
On 1/21/2026 3:18 PM, Ian Rogers wrote:
> On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
>> Diamond Rapids introduces two types of PCIe related uncore PMUs:
>> "uncore_pcie4_*" and "uncore_pcie6_*".
>>
>> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
>> and collect events from both PMU types, slightly relax the wildcard
>> matching logic in perf_pmu__match_wildcard().
>>
>> This change allows a wildcard such as "pcie" to match PMU names that
>> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
>>
>> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>> Signed-off-by: Zide Chen <zide.chen@intel.com>
> Can we not merge this. I'd missed a perf tool patch as it was hiding
> in a bunch of kernel uncore updates. At the very least if wildcard
> conventions are updated then the corresponding documentation needs
> updating:
> Documentation/ABI/testing/sysfs-bus-event_source-devices
Ian, thanks for the information. We didn't notice there is such
documentation to describe the name. :(
Besides the documentation, are there other comments? We can update it
together. Thanks.
>
> Thanks,
> Ian
>
>> ---
>> tools/perf/util/pmu.c | 14 ++++++++------
>> 1 file changed, 8 insertions(+), 6 deletions(-)
>>
>> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
>> index 956ea273c2c7..01a21b6aa031 100644
>> --- a/tools/perf/util/pmu.c
>> +++ b/tools/perf/util/pmu.c
>> @@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
>> {
>> const char *p, *suffix;
>> bool has_hex = false;
>> + bool has_underscore = false;
>> size_t tok_len = strlen(tok);
>>
>> /* Check start of pmu_name for equality. */
>> @@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
>> if (*p == 0)
>> return true;
>>
>> - if (*p == '_') {
>> - ++p;
>> - ++suffix;
>> - }
>> -
>> - /* Ensure we end in a number */
>> + /* Ensure we end in a number or a mix of number and "_". */
>> while (1) {
>> + if (!has_underscore && (*p == '_')) {
>> + has_underscore = true;
>> + ++p;
>> + ++suffix;
>> + }
>> +
>> if (!isxdigit(*p))
>> return false;
>> if (!has_hex)
>> --
>> 2.52.0
>>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2026-01-21 8:02 ` Mi, Dapeng
@ 2026-01-21 14:33 ` Ian Rogers
2026-01-21 18:19 ` Ian Rogers
0 siblings, 1 reply; 51+ messages in thread
From: Ian Rogers @ 2026-01-21 14:33 UTC (permalink / raw)
To: Mi, Dapeng
Cc: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Adrian Hunter, Alexander Shishkin, Andi Kleen,
Eranian Stephane, linux-kernel, linux-perf-users, Xudong Hao,
Falcon Thomas
On Wed, Jan 21, 2026 at 12:02 AM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
>
>
> On 1/21/2026 3:18 PM, Ian Rogers wrote:
> > On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
> >> Diamond Rapids introduces two types of PCIe related uncore PMUs:
> >> "uncore_pcie4_*" and "uncore_pcie6_*".
> >>
> >> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
> >> and collect events from both PMU types, slightly relax the wildcard
> >> matching logic in perf_pmu__match_wildcard().
> >>
> >> This change allows a wildcard such as "pcie" to match PMU names that
> >> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
> >>
> >> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> >> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> >> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> >> Signed-off-by: Zide Chen <zide.chen@intel.com>
> > Can we not merge this. I'd missed a perf tool patch as it was hiding
> > in a bunch of kernel uncore updates. At the very least if wildcard
> > conventions are updated then the corresponding documentation needs
> > updating:
> > Documentation/ABI/testing/sysfs-bus-event_source-devices
>
> Ian, thanks for the information. We didn't notice there is such
> documentation to describe the name. :(
>
> Besides the documentation, are there other comments? We can update it
> together. Thanks.
The suffix handling is notoriously brittle. For example, ARM added hex
suffixes which are generally 12 characters of physical address rather
than the typical _0, _1, etc. What could go wrong? Well in some
situations ARM make their core PMU's follow the model name, so rather
than armv8_pmuv3_0 the core pmu is a name that ends with a model
number something like _a76, however, that is also a valid hex suffix.
So we have bumped the hex suffix to be at least 2 characters:
https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmus.c?h=tmp.perf-tools-next#n81
This also works around the naming of s390 PMUs (comments in the code).
ARM now have models like a720ae which would appear as a 5 character
hex suffix, and so this whole hex suffix thing is hanging together for
some part because we treat core and uncore PMUs differently. From my
pov, ideally the ARM uncore PMUs would have just used the _0, _1, etc.
naming convention and placed the physical address information into a
caps file, rather than trying to shoehorn it into the PMU name.
s390 pmu names have discrepancies that mean lots of their core PMUs
can match suffixes and Intel's i915 PMU name ("i915") will happily
match as just "i" as the underscore before the number is optional. A
change like this needs a range of testing on a variety of
architectures because the code has broken things in a lot of different
architecture types.
Besides a lack of testing, going in through the wrong tree, the change
is changing suffix handling in one place but not all - at least
pmu_name_len_no_suffix wasn't updated. Let's get this out of the tree
and start again.
Thanks,
Ian
> >
> > Thanks,
> > Ian
> >
> >> ---
> >> tools/perf/util/pmu.c | 14 ++++++++------
> >> 1 file changed, 8 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> >> index 956ea273c2c7..01a21b6aa031 100644
> >> --- a/tools/perf/util/pmu.c
> >> +++ b/tools/perf/util/pmu.c
> >> @@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> >> {
> >> const char *p, *suffix;
> >> bool has_hex = false;
> >> + bool has_underscore = false;
> >> size_t tok_len = strlen(tok);
> >>
> >> /* Check start of pmu_name for equality. */
> >> @@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> >> if (*p == 0)
> >> return true;
> >>
> >> - if (*p == '_') {
> >> - ++p;
> >> - ++suffix;
> >> - }
> >> -
> >> - /* Ensure we end in a number */
> >> + /* Ensure we end in a number or a mix of number and "_". */
> >> while (1) {
> >> + if (!has_underscore && (*p == '_')) {
> >> + has_underscore = true;
> >> + ++p;
> >> + ++suffix;
> >> + }
> >> +
> >> if (!isxdigit(*p))
> >> return false;
> >> if (!has_hex)
> >> --
> >> 2.52.0
> >>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2026-01-21 14:33 ` Ian Rogers
@ 2026-01-21 18:19 ` Ian Rogers
2026-01-21 19:03 ` Chen, Zide
0 siblings, 1 reply; 51+ messages in thread
From: Ian Rogers @ 2026-01-21 18:19 UTC (permalink / raw)
To: Mi, Dapeng
Cc: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Adrian Hunter, Alexander Shishkin, Andi Kleen,
Eranian Stephane, linux-kernel, linux-perf-users, Xudong Hao,
Falcon Thomas
On Wed, Jan 21, 2026 at 6:33 AM Ian Rogers <irogers@google.com> wrote:
>
> On Wed, Jan 21, 2026 at 12:02 AM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
> >
> >
> > On 1/21/2026 3:18 PM, Ian Rogers wrote:
> > > On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
> > >> Diamond Rapids introduces two types of PCIe related uncore PMUs:
> > >> "uncore_pcie4_*" and "uncore_pcie6_*".
> > >>
> > >> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
> > >> and collect events from both PMU types, slightly relax the wildcard
> > >> matching logic in perf_pmu__match_wildcard().
> > >>
> > >> This change allows a wildcard such as "pcie" to match PMU names that
> > >> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
> > >>
> > >> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > >> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > >> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > >> Signed-off-by: Zide Chen <zide.chen@intel.com>
> > > Can we not merge this. I'd missed a perf tool patch as it was hiding
> > > in a bunch of kernel uncore updates. At the very least if wildcard
> > > conventions are updated then the corresponding documentation needs
> > > updating:
> > > Documentation/ABI/testing/sysfs-bus-event_source-devices
> >
> > Ian, thanks for the information. We didn't notice there is such
> > documentation to describe the name. :(
> >
> > Besides the documentation, are there other comments? We can update it
> > together. Thanks.
>
> The suffix handling is notoriously brittle. For example, ARM added hex
> suffixes which are generally 12 characters of physical address rather
> than the typical _0, _1, etc. What could go wrong? Well in some
> situations ARM make their core PMU's follow the model name, so rather
> than armv8_pmuv3_0 the core pmu is a name that ends with a model
> number something like _a76, however, that is also a valid hex suffix.
> So we have bumped the hex suffix to be at least 2 characters:
> https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmus.c?h=tmp.perf-tools-next#n81
> This also works around the naming of s390 PMUs (comments in the code).
> ARM now have models like a720ae which would appear as a 5 character
> hex suffix, and so this whole hex suffix thing is hanging together for
> some part because we treat core and uncore PMUs differently. From my
> pov, ideally the ARM uncore PMUs would have just used the _0, _1, etc.
> naming convention and placed the physical address information into a
> caps file, rather than trying to shoehorn it into the PMU name.
> s390 pmu names have discrepancies that mean lots of their core PMUs
> can match suffixes and Intel's i915 PMU name ("i915") will happily
> match as just "i" as the underscore before the number is optional. A
> change like this needs a range of testing on a variety of
> architectures because the code has broken things in a lot of different
> architecture types.
>
> Besides a lack of testing, going in through the wrong tree, the change
> is changing suffix handling in one place but not all - at least
> pmu_name_len_no_suffix wasn't updated. Let's get this out of the tree
> and start again.
To be explicit, things that I think are broken by this change:
1) ARM has PMUs called armv8_pmuv3_0, previously _0 would be the
suffix and now 3_0 becomes the suffix. There may be other existing
PMUs where this unintended behavioral change has happened. This may
break output formatting but I think as the patch is incomplete that
hasn't happened here.
2) as pmu_name_len_no_suffix wasn't updated it and assuming a machine
with uncore_pcie4_0, uncore_pcie4_1, uncore_pcie6_0, uncore_pcie6_1
and a common data_read event, the wildcarding for "pcie/data_read/"
should match the event on the 4 PMUs, however, rather than the PMU
name with no suffix (what pmu_name_len_no_suffix gives) being
uncore_pcie it will be either uncore_pcie4 or uncore_pcie6 depending
on which event/evsel we get the PMU name for. As the output will show
an aggregated amount the output for "perf stat -e pcie/data_read/ .."
the output may show just 1 event "pcie4/data_read/" rather than
"pcie/data_read/" as the suffix length calculation is off and the
number before the underscore not removed. In this example, it makes it
look like just 2 events on 2 PMUs were read rather than the full 4
events.
So my point is, resolving this is complex and needs buy-in and testing
from at least s390 and ARM. The easiest thing to do for now is to
drop/revert the change.
Thanks,
Ian
> Thanks,
> Ian
>
> > >
> > > Thanks,
> > > Ian
> > >
> > >> ---
> > >> tools/perf/util/pmu.c | 14 ++++++++------
> > >> 1 file changed, 8 insertions(+), 6 deletions(-)
> > >>
> > >> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> > >> index 956ea273c2c7..01a21b6aa031 100644
> > >> --- a/tools/perf/util/pmu.c
> > >> +++ b/tools/perf/util/pmu.c
> > >> @@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> > >> {
> > >> const char *p, *suffix;
> > >> bool has_hex = false;
> > >> + bool has_underscore = false;
> > >> size_t tok_len = strlen(tok);
> > >>
> > >> /* Check start of pmu_name for equality. */
> > >> @@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> > >> if (*p == 0)
> > >> return true;
> > >>
> > >> - if (*p == '_') {
> > >> - ++p;
> > >> - ++suffix;
> > >> - }
> > >> -
> > >> - /* Ensure we end in a number */
> > >> + /* Ensure we end in a number or a mix of number and "_". */
> > >> while (1) {
> > >> + if (!has_underscore && (*p == '_')) {
> > >> + has_underscore = true;
> > >> + ++p;
> > >> + ++suffix;
> > >> + }
> > >> +
> > >> if (!isxdigit(*p))
> > >> return false;
> > >> if (!has_hex)
> > >> --
> > >> 2.52.0
> > >>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2026-01-21 18:19 ` Ian Rogers
@ 2026-01-21 19:03 ` Chen, Zide
2026-01-22 2:09 ` Mi, Dapeng
0 siblings, 1 reply; 51+ messages in thread
From: Chen, Zide @ 2026-01-21 19:03 UTC (permalink / raw)
To: Ian Rogers, Mi, Dapeng
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Adrian Hunter, Alexander Shishkin, Andi Kleen,
Eranian Stephane, linux-kernel, linux-perf-users, Xudong Hao,
Falcon Thomas
On 1/21/2026 10:19 AM, Ian Rogers wrote:
> On Wed, Jan 21, 2026 at 6:33 AM Ian Rogers <irogers@google.com> wrote:
>>
>> On Wed, Jan 21, 2026 at 12:02 AM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
>>>
>>>
>>> On 1/21/2026 3:18 PM, Ian Rogers wrote:
>>>> On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
>>>>> Diamond Rapids introduces two types of PCIe related uncore PMUs:
>>>>> "uncore_pcie4_*" and "uncore_pcie6_*".
>>>>>
>>>>> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
>>>>> and collect events from both PMU types, slightly relax the wildcard
>>>>> matching logic in perf_pmu__match_wildcard().
>>>>>
>>>>> This change allows a wildcard such as "pcie" to match PMU names that
>>>>> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
>>>>>
>>>>> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>>>>> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>>>>> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>>>>> Signed-off-by: Zide Chen <zide.chen@intel.com>
>>>> Can we not merge this. I'd missed a perf tool patch as it was hiding
>>>> in a bunch of kernel uncore updates. At the very least if wildcard
>>>> conventions are updated then the corresponding documentation needs
>>>> updating:
>>>> Documentation/ABI/testing/sysfs-bus-event_source-devices
>>>
>>> Ian, thanks for the information. We didn't notice there is such
>>> documentation to describe the name. :(
>>>
>>> Besides the documentation, are there other comments? We can update it
>>> together. Thanks.
>>
>> The suffix handling is notoriously brittle. For example, ARM added hex
>> suffixes which are generally 12 characters of physical address rather
>> than the typical _0, _1, etc. What could go wrong? Well in some
>> situations ARM make their core PMU's follow the model name, so rather
>> than armv8_pmuv3_0 the core pmu is a name that ends with a model
>> number something like _a76, however, that is also a valid hex suffix.
>> So we have bumped the hex suffix to be at least 2 characters:
>> https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmus.c?h=tmp.perf-tools-next#n81
>> This also works around the naming of s390 PMUs (comments in the code).
>> ARM now have models like a720ae which would appear as a 5 character
>> hex suffix, and so this whole hex suffix thing is hanging together for
>> some part because we treat core and uncore PMUs differently. From my
>> pov, ideally the ARM uncore PMUs would have just used the _0, _1, etc.
>> naming convention and placed the physical address information into a
>> caps file, rather than trying to shoehorn it into the PMU name.
>> s390 pmu names have discrepancies that mean lots of their core PMUs
>> can match suffixes and Intel's i915 PMU name ("i915") will happily
>> match as just "i" as the underscore before the number is optional. A
>> change like this needs a range of testing on a variety of
>> architectures because the code has broken things in a lot of different
>> architecture types.
>>
>> Besides a lack of testing, going in through the wrong tree, the change
>> is changing suffix handling in one place but not all - at least
>> pmu_name_len_no_suffix wasn't updated. Let's get this out of the tree
>> and start again.
>
> To be explicit, things that I think are broken by this change:
>
> 1) ARM has PMUs called armv8_pmuv3_0, previously _0 would be the
> suffix and now 3_0 becomes the suffix. There may be other existing
> PMUs where this unintended behavioral change has happened. This may
> break output formatting but I think as the patch is incomplete that
> hasn't happened here.
>
> 2) as pmu_name_len_no_suffix wasn't updated it and assuming a machine
> with uncore_pcie4_0, uncore_pcie4_1, uncore_pcie6_0, uncore_pcie6_1
> and a common data_read event, the wildcarding for "pcie/data_read/"
> should match the event on the 4 PMUs, however, rather than the PMU
> name with no suffix (what pmu_name_len_no_suffix gives) being
> uncore_pcie it will be either uncore_pcie4 or uncore_pcie6 depending
> on which event/evsel we get the PMU name for. As the output will show
> an aggregated amount the output for "perf stat -e pcie/data_read/ .."
> the output may show just 1 event "pcie4/data_read/" rather than
> "pcie/data_read/" as the suffix length calculation is off and the
> number before the underscore not removed. In this example, it makes it
> look like just 2 events on 2 PMUs were read rather than the full 4
> events.
>
> So my point is, resolving this is complex and needs buy-in and testing
> from at least s390 and ARM. The easiest thing to do for now is to
> drop/revert the change.
Agreed. Thank you very much for pointing this out!
> Thanks,
> Ian
>
>> Thanks,
>> Ian
>>
>>>>
>>>> Thanks,
>>>> Ian
>>>>
>>>>> ---
>>>>> tools/perf/util/pmu.c | 14 ++++++++------
>>>>> 1 file changed, 8 insertions(+), 6 deletions(-)
>>>>>
>>>>> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
>>>>> index 956ea273c2c7..01a21b6aa031 100644
>>>>> --- a/tools/perf/util/pmu.c
>>>>> +++ b/tools/perf/util/pmu.c
>>>>> @@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
>>>>> {
>>>>> const char *p, *suffix;
>>>>> bool has_hex = false;
>>>>> + bool has_underscore = false;
>>>>> size_t tok_len = strlen(tok);
>>>>>
>>>>> /* Check start of pmu_name for equality. */
>>>>> @@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
>>>>> if (*p == 0)
>>>>> return true;
>>>>>
>>>>> - if (*p == '_') {
>>>>> - ++p;
>>>>> - ++suffix;
>>>>> - }
>>>>> -
>>>>> - /* Ensure we end in a number */
>>>>> + /* Ensure we end in a number or a mix of number and "_". */
>>>>> while (1) {
>>>>> + if (!has_underscore && (*p == '_')) {
>>>>> + has_underscore = true;
>>>>> + ++p;
>>>>> + ++suffix;
>>>>> + }
>>>>> +
>>>>> if (!isxdigit(*p))
>>>>> return false;
>>>>> if (!has_hex)
>>>>> --
>>>>> 2.52.0
>>>>>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2026-01-21 19:03 ` Chen, Zide
@ 2026-01-22 2:09 ` Mi, Dapeng
2026-01-22 7:10 ` Ian Rogers
0 siblings, 1 reply; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-22 2:09 UTC (permalink / raw)
To: Chen, Zide, Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Adrian Hunter, Alexander Shishkin, Andi Kleen,
Eranian Stephane, linux-kernel, linux-perf-users, Xudong Hao,
Falcon Thomas
On 1/22/2026 3:03 AM, Chen, Zide wrote:
>
> On 1/21/2026 10:19 AM, Ian Rogers wrote:
>> On Wed, Jan 21, 2026 at 6:33 AM Ian Rogers <irogers@google.com> wrote:
>>> On Wed, Jan 21, 2026 at 12:02 AM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
>>>>
>>>> On 1/21/2026 3:18 PM, Ian Rogers wrote:
>>>>> On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
>>>>>> Diamond Rapids introduces two types of PCIe related uncore PMUs:
>>>>>> "uncore_pcie4_*" and "uncore_pcie6_*".
>>>>>>
>>>>>> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
>>>>>> and collect events from both PMU types, slightly relax the wildcard
>>>>>> matching logic in perf_pmu__match_wildcard().
>>>>>>
>>>>>> This change allows a wildcard such as "pcie" to match PMU names that
>>>>>> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
>>>>>>
>>>>>> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>>>>>> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>>>>>> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>>>>>> Signed-off-by: Zide Chen <zide.chen@intel.com>
>>>>> Can we not merge this. I'd missed a perf tool patch as it was hiding
>>>>> in a bunch of kernel uncore updates. At the very least if wildcard
>>>>> conventions are updated then the corresponding documentation needs
>>>>> updating:
>>>>> Documentation/ABI/testing/sysfs-bus-event_source-devices
>>>> Ian, thanks for the information. We didn't notice there is such
>>>> documentation to describe the name. :(
>>>>
>>>> Besides the documentation, are there other comments? We can update it
>>>> together. Thanks.
>>> The suffix handling is notoriously brittle. For example, ARM added hex
>>> suffixes which are generally 12 characters of physical address rather
>>> than the typical _0, _1, etc. What could go wrong? Well in some
>>> situations ARM make their core PMU's follow the model name, so rather
>>> than armv8_pmuv3_0 the core pmu is a name that ends with a model
>>> number something like _a76, however, that is also a valid hex suffix.
>>> So we have bumped the hex suffix to be at least 2 characters:
>>> https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmus.c?h=tmp.perf-tools-next#n81
>>> This also works around the naming of s390 PMUs (comments in the code).
>>> ARM now have models like a720ae which would appear as a 5 character
>>> hex suffix, and so this whole hex suffix thing is hanging together for
>>> some part because we treat core and uncore PMUs differently. From my
>>> pov, ideally the ARM uncore PMUs would have just used the _0, _1, etc.
>>> naming convention and placed the physical address information into a
>>> caps file, rather than trying to shoehorn it into the PMU name.
>>> s390 pmu names have discrepancies that mean lots of their core PMUs
>>> can match suffixes and Intel's i915 PMU name ("i915") will happily
>>> match as just "i" as the underscore before the number is optional. A
>>> change like this needs a range of testing on a variety of
>>> architectures because the code has broken things in a lot of different
>>> architecture types.
>>>
>>> Besides a lack of testing, going in through the wrong tree, the change
>>> is changing suffix handling in one place but not all - at least
>>> pmu_name_len_no_suffix wasn't updated. Let's get this out of the tree
>>> and start again.
>> To be explicit, things that I think are broken by this change:
>>
>> 1) ARM has PMUs called armv8_pmuv3_0, previously _0 would be the
>> suffix and now 3_0 becomes the suffix. There may be other existing
>> PMUs where this unintended behavioral change has happened. This may
>> break output formatting but I think as the patch is incomplete that
>> hasn't happened here.
>>
>> 2) as pmu_name_len_no_suffix wasn't updated it and assuming a machine
>> with uncore_pcie4_0, uncore_pcie4_1, uncore_pcie6_0, uncore_pcie6_1
>> and a common data_read event, the wildcarding for "pcie/data_read/"
>> should match the event on the 4 PMUs, however, rather than the PMU
>> name with no suffix (what pmu_name_len_no_suffix gives) being
>> uncore_pcie it will be either uncore_pcie4 or uncore_pcie6 depending
>> on which event/evsel we get the PMU name for. As the output will show
>> an aggregated amount the output for "perf stat -e pcie/data_read/ .."
>> the output may show just 1 event "pcie4/data_read/" rather than
>> "pcie/data_read/" as the suffix length calculation is off and the
>> number before the underscore not removed. In this example, it makes it
>> look like just 2 events on 2 PMUs were read rather than the full 4
>> events.
>>
>> So my point is, resolving this is complex and needs buy-in and testing
>> from at least s390 and ARM. The easiest thing to do for now is to
>> drop/revert the change.
Sigh, the PMU name wildcard comparison is over complicated than I imagine...
I have no objection to drop this specific perf tools patch. Thanks.
> Agreed. Thank you very much for pointing this out!
>
>
>> Thanks,
>> Ian
>>
>>> Thanks,
>>> Ian
>>>
>>>>> Thanks,
>>>>> Ian
>>>>>
>>>>>> ---
>>>>>> tools/perf/util/pmu.c | 14 ++++++++------
>>>>>> 1 file changed, 8 insertions(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
>>>>>> index 956ea273c2c7..01a21b6aa031 100644
>>>>>> --- a/tools/perf/util/pmu.c
>>>>>> +++ b/tools/perf/util/pmu.c
>>>>>> @@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
>>>>>> {
>>>>>> const char *p, *suffix;
>>>>>> bool has_hex = false;
>>>>>> + bool has_underscore = false;
>>>>>> size_t tok_len = strlen(tok);
>>>>>>
>>>>>> /* Check start of pmu_name for equality. */
>>>>>> @@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
>>>>>> if (*p == 0)
>>>>>> return true;
>>>>>>
>>>>>> - if (*p == '_') {
>>>>>> - ++p;
>>>>>> - ++suffix;
>>>>>> - }
>>>>>> -
>>>>>> - /* Ensure we end in a number */
>>>>>> + /* Ensure we end in a number or a mix of number and "_". */
>>>>>> while (1) {
>>>>>> + if (!has_underscore && (*p == '_')) {
>>>>>> + has_underscore = true;
>>>>>> + ++p;
>>>>>> + ++suffix;
>>>>>> + }
>>>>>> +
>>>>>> if (!isxdigit(*p))
>>>>>> return false;
>>>>>> if (!has_hex)
>>>>>> --
>>>>>> 2.52.0
>>>>>>
>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2026-01-22 2:09 ` Mi, Dapeng
@ 2026-01-22 7:10 ` Ian Rogers
2026-02-03 23:33 ` Ian Rogers
0 siblings, 1 reply; 51+ messages in thread
From: Ian Rogers @ 2026-01-22 7:10 UTC (permalink / raw)
To: Mi, Dapeng
Cc: Chen, Zide, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Adrian Hunter, Alexander Shishkin, Andi Kleen,
Eranian Stephane, linux-kernel, linux-perf-users, Xudong Hao,
Falcon Thomas
On Wed, Jan 21, 2026 at 6:10 PM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
>
>
> On 1/22/2026 3:03 AM, Chen, Zide wrote:
> >
> > On 1/21/2026 10:19 AM, Ian Rogers wrote:
> >> On Wed, Jan 21, 2026 at 6:33 AM Ian Rogers <irogers@google.com> wrote:
> >>> On Wed, Jan 21, 2026 at 12:02 AM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
> >>>>
> >>>> On 1/21/2026 3:18 PM, Ian Rogers wrote:
> >>>>> On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
> >>>>>> Diamond Rapids introduces two types of PCIe related uncore PMUs:
> >>>>>> "uncore_pcie4_*" and "uncore_pcie6_*".
> >>>>>>
> >>>>>> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
> >>>>>> and collect events from both PMU types, slightly relax the wildcard
> >>>>>> matching logic in perf_pmu__match_wildcard().
> >>>>>>
> >>>>>> This change allows a wildcard such as "pcie" to match PMU names that
> >>>>>> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
> >>>>>>
> >>>>>> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> >>>>>> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> >>>>>> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> >>>>>> Signed-off-by: Zide Chen <zide.chen@intel.com>
> >>>>> Can we not merge this. I'd missed a perf tool patch as it was hiding
> >>>>> in a bunch of kernel uncore updates. At the very least if wildcard
> >>>>> conventions are updated then the corresponding documentation needs
> >>>>> updating:
> >>>>> Documentation/ABI/testing/sysfs-bus-event_source-devices
> >>>> Ian, thanks for the information. We didn't notice there is such
> >>>> documentation to describe the name. :(
> >>>>
> >>>> Besides the documentation, are there other comments? We can update it
> >>>> together. Thanks.
> >>> The suffix handling is notoriously brittle. For example, ARM added hex
> >>> suffixes which are generally 12 characters of physical address rather
> >>> than the typical _0, _1, etc. What could go wrong? Well in some
> >>> situations ARM make their core PMU's follow the model name, so rather
> >>> than armv8_pmuv3_0 the core pmu is a name that ends with a model
> >>> number something like _a76, however, that is also a valid hex suffix.
> >>> So we have bumped the hex suffix to be at least 2 characters:
> >>> https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmus.c?h=tmp.perf-tools-next#n81
> >>> This also works around the naming of s390 PMUs (comments in the code).
> >>> ARM now have models like a720ae which would appear as a 5 character
> >>> hex suffix, and so this whole hex suffix thing is hanging together for
> >>> some part because we treat core and uncore PMUs differently. From my
> >>> pov, ideally the ARM uncore PMUs would have just used the _0, _1, etc.
> >>> naming convention and placed the physical address information into a
> >>> caps file, rather than trying to shoehorn it into the PMU name.
> >>> s390 pmu names have discrepancies that mean lots of their core PMUs
> >>> can match suffixes and Intel's i915 PMU name ("i915") will happily
> >>> match as just "i" as the underscore before the number is optional. A
> >>> change like this needs a range of testing on a variety of
> >>> architectures because the code has broken things in a lot of different
> >>> architecture types.
> >>>
> >>> Besides a lack of testing, going in through the wrong tree, the change
> >>> is changing suffix handling in one place but not all - at least
> >>> pmu_name_len_no_suffix wasn't updated. Let's get this out of the tree
> >>> and start again.
> >> To be explicit, things that I think are broken by this change:
> >>
> >> 1) ARM has PMUs called armv8_pmuv3_0, previously _0 would be the
> >> suffix and now 3_0 becomes the suffix. There may be other existing
> >> PMUs where this unintended behavioral change has happened. This may
> >> break output formatting but I think as the patch is incomplete that
> >> hasn't happened here.
> >>
> >> 2) as pmu_name_len_no_suffix wasn't updated it and assuming a machine
> >> with uncore_pcie4_0, uncore_pcie4_1, uncore_pcie6_0, uncore_pcie6_1
> >> and a common data_read event, the wildcarding for "pcie/data_read/"
> >> should match the event on the 4 PMUs, however, rather than the PMU
> >> name with no suffix (what pmu_name_len_no_suffix gives) being
> >> uncore_pcie it will be either uncore_pcie4 or uncore_pcie6 depending
> >> on which event/evsel we get the PMU name for. As the output will show
> >> an aggregated amount the output for "perf stat -e pcie/data_read/ .."
> >> the output may show just 1 event "pcie4/data_read/" rather than
> >> "pcie/data_read/" as the suffix length calculation is off and the
> >> number before the underscore not removed. In this example, it makes it
> >> look like just 2 events on 2 PMUs were read rather than the full 4
> >> events.
> >>
> >> So my point is, resolving this is complex and needs buy-in and testing
> >> from at least s390 and ARM. The easiest thing to do for now is to
> >> drop/revert the change.
>
> Sigh, the PMU name wildcard comparison is over complicated than I imagine...
Agreed. One proposal from chatting with Namhyung is that in the future
we have some PMU base name file in sysfs, this will be used for
wildcard matching, giving the name with no suffix, etc. At some future
point that may allow us to not care about all of these overloaded uses
for the PMU name.
Thanks,
Ian
> I have no objection to drop this specific perf tools patch. Thanks.
>
>
> > Agreed. Thank you very much for pointing this out!
> >
> >
> >> Thanks,
> >> Ian
> >>
> >>> Thanks,
> >>> Ian
> >>>
> >>>>> Thanks,
> >>>>> Ian
> >>>>>
> >>>>>> ---
> >>>>>> tools/perf/util/pmu.c | 14 ++++++++------
> >>>>>> 1 file changed, 8 insertions(+), 6 deletions(-)
> >>>>>>
> >>>>>> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> >>>>>> index 956ea273c2c7..01a21b6aa031 100644
> >>>>>> --- a/tools/perf/util/pmu.c
> >>>>>> +++ b/tools/perf/util/pmu.c
> >>>>>> @@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> >>>>>> {
> >>>>>> const char *p, *suffix;
> >>>>>> bool has_hex = false;
> >>>>>> + bool has_underscore = false;
> >>>>>> size_t tok_len = strlen(tok);
> >>>>>>
> >>>>>> /* Check start of pmu_name for equality. */
> >>>>>> @@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> >>>>>> if (*p == 0)
> >>>>>> return true;
> >>>>>>
> >>>>>> - if (*p == '_') {
> >>>>>> - ++p;
> >>>>>> - ++suffix;
> >>>>>> - }
> >>>>>> -
> >>>>>> - /* Ensure we end in a number */
> >>>>>> + /* Ensure we end in a number or a mix of number and "_". */
> >>>>>> while (1) {
> >>>>>> + if (!has_underscore && (*p == '_')) {
> >>>>>> + has_underscore = true;
> >>>>>> + ++p;
> >>>>>> + ++suffix;
> >>>>>> + }
> >>>>>> +
> >>>>>> if (!isxdigit(*p))
> >>>>>> return false;
> >>>>>> if (!has_hex)
> >>>>>> --
> >>>>>> 2.52.0
> >>>>>>
> >
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2026-01-22 7:10 ` Ian Rogers
@ 2026-02-03 23:33 ` Ian Rogers
2026-02-04 21:34 ` Namhyung Kim
0 siblings, 1 reply; 51+ messages in thread
From: Ian Rogers @ 2026-02-03 23:33 UTC (permalink / raw)
To: Mi, Dapeng
Cc: Chen, Zide, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Adrian Hunter, Alexander Shishkin, Andi Kleen,
Eranian Stephane, linux-kernel, linux-perf-users, Xudong Hao,
Falcon Thomas
On Wed, Jan 21, 2026 at 11:10 PM Ian Rogers <irogers@google.com> wrote:
>
> On Wed, Jan 21, 2026 at 6:10 PM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
> >
> >
> > On 1/22/2026 3:03 AM, Chen, Zide wrote:
> > >
> > > On 1/21/2026 10:19 AM, Ian Rogers wrote:
> > >> On Wed, Jan 21, 2026 at 6:33 AM Ian Rogers <irogers@google.com> wrote:
> > >>> On Wed, Jan 21, 2026 at 12:02 AM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
> > >>>>
> > >>>> On 1/21/2026 3:18 PM, Ian Rogers wrote:
> > >>>>> On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
> > >>>>>> Diamond Rapids introduces two types of PCIe related uncore PMUs:
> > >>>>>> "uncore_pcie4_*" and "uncore_pcie6_*".
> > >>>>>>
> > >>>>>> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
> > >>>>>> and collect events from both PMU types, slightly relax the wildcard
> > >>>>>> matching logic in perf_pmu__match_wildcard().
> > >>>>>>
> > >>>>>> This change allows a wildcard such as "pcie" to match PMU names that
> > >>>>>> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
> > >>>>>>
> > >>>>>> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > >>>>>> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > >>>>>> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > >>>>>> Signed-off-by: Zide Chen <zide.chen@intel.com>
> > >>>>> Can we not merge this. I'd missed a perf tool patch as it was hiding
> > >>>>> in a bunch of kernel uncore updates. At the very least if wildcard
> > >>>>> conventions are updated then the corresponding documentation needs
> > >>>>> updating:
> > >>>>> Documentation/ABI/testing/sysfs-bus-event_source-devices
> > >>>> Ian, thanks for the information. We didn't notice there is such
> > >>>> documentation to describe the name. :(
> > >>>>
> > >>>> Besides the documentation, are there other comments? We can update it
> > >>>> together. Thanks.
> > >>> The suffix handling is notoriously brittle. For example, ARM added hex
> > >>> suffixes which are generally 12 characters of physical address rather
> > >>> than the typical _0, _1, etc. What could go wrong? Well in some
> > >>> situations ARM make their core PMU's follow the model name, so rather
> > >>> than armv8_pmuv3_0 the core pmu is a name that ends with a model
> > >>> number something like _a76, however, that is also a valid hex suffix.
> > >>> So we have bumped the hex suffix to be at least 2 characters:
> > >>> https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmus.c?h=tmp.perf-tools-next#n81
> > >>> This also works around the naming of s390 PMUs (comments in the code).
> > >>> ARM now have models like a720ae which would appear as a 5 character
> > >>> hex suffix, and so this whole hex suffix thing is hanging together for
> > >>> some part because we treat core and uncore PMUs differently. From my
> > >>> pov, ideally the ARM uncore PMUs would have just used the _0, _1, etc.
> > >>> naming convention and placed the physical address information into a
> > >>> caps file, rather than trying to shoehorn it into the PMU name.
> > >>> s390 pmu names have discrepancies that mean lots of their core PMUs
> > >>> can match suffixes and Intel's i915 PMU name ("i915") will happily
> > >>> match as just "i" as the underscore before the number is optional. A
> > >>> change like this needs a range of testing on a variety of
> > >>> architectures because the code has broken things in a lot of different
> > >>> architecture types.
> > >>>
> > >>> Besides a lack of testing, going in through the wrong tree, the change
> > >>> is changing suffix handling in one place but not all - at least
> > >>> pmu_name_len_no_suffix wasn't updated. Let's get this out of the tree
> > >>> and start again.
> > >> To be explicit, things that I think are broken by this change:
> > >>
> > >> 1) ARM has PMUs called armv8_pmuv3_0, previously _0 would be the
> > >> suffix and now 3_0 becomes the suffix. There may be other existing
> > >> PMUs where this unintended behavioral change has happened. This may
> > >> break output formatting but I think as the patch is incomplete that
> > >> hasn't happened here.
> > >>
> > >> 2) as pmu_name_len_no_suffix wasn't updated it and assuming a machine
> > >> with uncore_pcie4_0, uncore_pcie4_1, uncore_pcie6_0, uncore_pcie6_1
> > >> and a common data_read event, the wildcarding for "pcie/data_read/"
> > >> should match the event on the 4 PMUs, however, rather than the PMU
> > >> name with no suffix (what pmu_name_len_no_suffix gives) being
> > >> uncore_pcie it will be either uncore_pcie4 or uncore_pcie6 depending
> > >> on which event/evsel we get the PMU name for. As the output will show
> > >> an aggregated amount the output for "perf stat -e pcie/data_read/ .."
> > >> the output may show just 1 event "pcie4/data_read/" rather than
> > >> "pcie/data_read/" as the suffix length calculation is off and the
> > >> number before the underscore not removed. In this example, it makes it
> > >> look like just 2 events on 2 PMUs were read rather than the full 4
> > >> events.
> > >>
> > >> So my point is, resolving this is complex and needs buy-in and testing
> > >> from at least s390 and ARM. The easiest thing to do for now is to
> > >> drop/revert the change.
> >
> > Sigh, the PMU name wildcard comparison is over complicated than I imagine...
>
> Agreed. One proposal from chatting with Namhyung is that in the future
> we have some PMU base name file in sysfs, this will be used for
> wildcard matching, giving the name with no suffix, etc. At some future
> point that may allow us to not care about all of these overloaded uses
> for the PMU name.
>
> Thanks,
> Ian
>
> > I have no objection to drop this specific perf tools patch. Thanks.
I'm still seeing this patch in tip.git:
https://web.git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/tools/perf/util/pmu.c?h=perf/core&id=2246c24426fbc1069cb2a47e0624ccffe5f2627b
with no revert:
https://web.git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/log/tools/perf/util/pmu.c?h=perf/core
Thanks,
Ian
> >
> >
> > > Agreed. Thank you very much for pointing this out!
> > >
> > >
> > >> Thanks,
> > >> Ian
> > >>
> > >>> Thanks,
> > >>> Ian
> > >>>
> > >>>>> Thanks,
> > >>>>> Ian
> > >>>>>
> > >>>>>> ---
> > >>>>>> tools/perf/util/pmu.c | 14 ++++++++------
> > >>>>>> 1 file changed, 8 insertions(+), 6 deletions(-)
> > >>>>>>
> > >>>>>> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> > >>>>>> index 956ea273c2c7..01a21b6aa031 100644
> > >>>>>> --- a/tools/perf/util/pmu.c
> > >>>>>> +++ b/tools/perf/util/pmu.c
> > >>>>>> @@ -939,6 +939,7 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> > >>>>>> {
> > >>>>>> const char *p, *suffix;
> > >>>>>> bool has_hex = false;
> > >>>>>> + bool has_underscore = false;
> > >>>>>> size_t tok_len = strlen(tok);
> > >>>>>>
> > >>>>>> /* Check start of pmu_name for equality. */
> > >>>>>> @@ -949,13 +950,14 @@ static bool perf_pmu__match_wildcard(const char *pmu_name, const char *tok)
> > >>>>>> if (*p == 0)
> > >>>>>> return true;
> > >>>>>>
> > >>>>>> - if (*p == '_') {
> > >>>>>> - ++p;
> > >>>>>> - ++suffix;
> > >>>>>> - }
> > >>>>>> -
> > >>>>>> - /* Ensure we end in a number */
> > >>>>>> + /* Ensure we end in a number or a mix of number and "_". */
> > >>>>>> while (1) {
> > >>>>>> + if (!has_underscore && (*p == '_')) {
> > >>>>>> + has_underscore = true;
> > >>>>>> + ++p;
> > >>>>>> + ++suffix;
> > >>>>>> + }
> > >>>>>> +
> > >>>>>> if (!isxdigit(*p))
> > >>>>>> return false;
> > >>>>>> if (!has_hex)
> > >>>>>> --
> > >>>>>> 2.52.0
> > >>>>>>
> > >
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2026-02-03 23:33 ` Ian Rogers
@ 2026-02-04 21:34 ` Namhyung Kim
0 siblings, 0 replies; 51+ messages in thread
From: Namhyung Kim @ 2026-02-04 21:34 UTC (permalink / raw)
To: Ian Rogers, Peter Zijlstra, Ingo Molnar
Cc: Mi, Dapeng, Chen, Zide, Arnaldo Carvalho de Melo, Adrian Hunter,
Alexander Shishkin, Andi Kleen, Eranian Stephane, linux-kernel,
linux-perf-users, Xudong Hao, Falcon Thomas
Hi Peter and Ingo,
On Tue, Feb 03, 2026 at 03:33:07PM -0800, Ian Rogers wrote:
> On Wed, Jan 21, 2026 at 11:10 PM Ian Rogers <irogers@google.com> wrote:
> >
> > On Wed, Jan 21, 2026 at 6:10 PM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
> > >
> > >
> > > On 1/22/2026 3:03 AM, Chen, Zide wrote:
> > > >
> > > > On 1/21/2026 10:19 AM, Ian Rogers wrote:
> > > >> On Wed, Jan 21, 2026 at 6:33 AM Ian Rogers <irogers@google.com> wrote:
> > > >>> On Wed, Jan 21, 2026 at 12:02 AM Mi, Dapeng <dapeng1.mi@linux.intel.com> wrote:
> > > >>>>
> > > >>>> On 1/21/2026 3:18 PM, Ian Rogers wrote:
> > > >>>>> On Wed, Dec 31, 2025 at 2:49 PM Zide Chen <zide.chen@intel.com> wrote:
> > > >>>>>> Diamond Rapids introduces two types of PCIe related uncore PMUs:
> > > >>>>>> "uncore_pcie4_*" and "uncore_pcie6_*".
> > > >>>>>>
> > > >>>>>> To ensure that generic PCIe events (e.g., UNC_PCIE_CLOCKTICKS) can match
> > > >>>>>> and collect events from both PMU types, slightly relax the wildcard
> > > >>>>>> matching logic in perf_pmu__match_wildcard().
> > > >>>>>>
> > > >>>>>> This change allows a wildcard such as "pcie" to match PMU names that
> > > >>>>>> include a numeric suffix, such as "pcie4_*" and "pcie6_*".
> > > >>>>>>
> > > >>>>>> Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > > >>>>>> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > > >>>>>> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> > > >>>>>> Signed-off-by: Zide Chen <zide.chen@intel.com>
> > > >>>>> Can we not merge this. I'd missed a perf tool patch as it was hiding
> > > >>>>> in a bunch of kernel uncore updates. At the very least if wildcard
> > > >>>>> conventions are updated then the corresponding documentation needs
> > > >>>>> updating:
> > > >>>>> Documentation/ABI/testing/sysfs-bus-event_source-devices
> > > >>>> Ian, thanks for the information. We didn't notice there is such
> > > >>>> documentation to describe the name. :(
> > > >>>>
> > > >>>> Besides the documentation, are there other comments? We can update it
> > > >>>> together. Thanks.
> > > >>> The suffix handling is notoriously brittle. For example, ARM added hex
> > > >>> suffixes which are generally 12 characters of physical address rather
> > > >>> than the typical _0, _1, etc. What could go wrong? Well in some
> > > >>> situations ARM make their core PMU's follow the model name, so rather
> > > >>> than armv8_pmuv3_0 the core pmu is a name that ends with a model
> > > >>> number something like _a76, however, that is also a valid hex suffix.
> > > >>> So we have bumped the hex suffix to be at least 2 characters:
> > > >>> https://web.git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/pmus.c?h=tmp.perf-tools-next#n81
> > > >>> This also works around the naming of s390 PMUs (comments in the code).
> > > >>> ARM now have models like a720ae which would appear as a 5 character
> > > >>> hex suffix, and so this whole hex suffix thing is hanging together for
> > > >>> some part because we treat core and uncore PMUs differently. From my
> > > >>> pov, ideally the ARM uncore PMUs would have just used the _0, _1, etc.
> > > >>> naming convention and placed the physical address information into a
> > > >>> caps file, rather than trying to shoehorn it into the PMU name.
> > > >>> s390 pmu names have discrepancies that mean lots of their core PMUs
> > > >>> can match suffixes and Intel's i915 PMU name ("i915") will happily
> > > >>> match as just "i" as the underscore before the number is optional. A
> > > >>> change like this needs a range of testing on a variety of
> > > >>> architectures because the code has broken things in a lot of different
> > > >>> architecture types.
> > > >>>
> > > >>> Besides a lack of testing, going in through the wrong tree, the change
> > > >>> is changing suffix handling in one place but not all - at least
> > > >>> pmu_name_len_no_suffix wasn't updated. Let's get this out of the tree
> > > >>> and start again.
> > > >> To be explicit, things that I think are broken by this change:
> > > >>
> > > >> 1) ARM has PMUs called armv8_pmuv3_0, previously _0 would be the
> > > >> suffix and now 3_0 becomes the suffix. There may be other existing
> > > >> PMUs where this unintended behavioral change has happened. This may
> > > >> break output formatting but I think as the patch is incomplete that
> > > >> hasn't happened here.
> > > >>
> > > >> 2) as pmu_name_len_no_suffix wasn't updated it and assuming a machine
> > > >> with uncore_pcie4_0, uncore_pcie4_1, uncore_pcie6_0, uncore_pcie6_1
> > > >> and a common data_read event, the wildcarding for "pcie/data_read/"
> > > >> should match the event on the 4 PMUs, however, rather than the PMU
> > > >> name with no suffix (what pmu_name_len_no_suffix gives) being
> > > >> uncore_pcie it will be either uncore_pcie4 or uncore_pcie6 depending
> > > >> on which event/evsel we get the PMU name for. As the output will show
> > > >> an aggregated amount the output for "perf stat -e pcie/data_read/ .."
> > > >> the output may show just 1 event "pcie4/data_read/" rather than
> > > >> "pcie/data_read/" as the suffix length calculation is off and the
> > > >> number before the underscore not removed. In this example, it makes it
> > > >> look like just 2 events on 2 PMUs were read rather than the full 4
> > > >> events.
> > > >>
> > > >> So my point is, resolving this is complex and needs buy-in and testing
> > > >> from at least s390 and ARM. The easiest thing to do for now is to
> > > >> drop/revert the change.
> > >
> > > Sigh, the PMU name wildcard comparison is over complicated than I imagine...
> >
> > Agreed. One proposal from chatting with Namhyung is that in the future
> > we have some PMU base name file in sysfs, this will be used for
> > wildcard matching, giving the name with no suffix, etc. At some future
> > point that may allow us to not care about all of these overloaded uses
> > for the PMU name.
> >
> > Thanks,
> > Ian
> >
> > > I have no objection to drop this specific perf tools patch. Thanks.
>
> I'm still seeing this patch in tip.git:
> https://web.git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/tools/perf/util/pmu.c?h=perf/core&id=2246c24426fbc1069cb2a47e0624ccffe5f2627b
> with no revert:
> https://web.git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/log/tools/perf/util/pmu.c?h=perf/core
Can you please revert the commit? I know it's late in the cycle but Ian
found an issue in the tooling. And in general, it'd be nice if all tool
changes can go through the perf-tools tree.
Of course, we can revert it and add changes in the tools tree for the
next cycle. Let me know what you think.
Thanks,
Namhyung
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH V2 12/13] perf/x86/intel/uncore: Add missing PMON units for Panther Lake
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (10 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 11/13] perf pmu: Relax uncore wildcard matching to allow numeric suffix Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 2:48 ` Mi, Dapeng
` (2 more replies)
2025-12-31 22:42 ` [PATCH V2 13/13] perf/x86/intel/uncore: Add Nova Lake support Zide Chen
2026-01-06 15:08 ` [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Peter Zijlstra
13 siblings, 3 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
Besides CBOX, Panther Lake includes several legacy uncore PMON units
not enumerated via discovery tables, including cNCU, SANTA, and
ia_core_bridge.
The cNCU PMON is similar to Meteor Lake but has two boxes with two
counters each. SANTA and IA Core Bridge PMON units follow the legacy
model used on Lunar Lake, Meteor Lake, and others.
Panther Lake implements the Global Control Register; the freeze_all bit
must be cleared before programming counters.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2: new patch
arch/x86/events/intel/uncore.c | 1 +
arch/x86/events/intel/uncore_snb.c | 45 ++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 54b3c1e3af32..07a9a2826398 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1814,6 +1814,7 @@ static const struct uncore_plat_init ptl_uncore_init __initconst = {
.cpu_init = ptl_uncore_cpu_init,
.mmio_init = ptl_uncore_mmio_init,
.domain[0].discovery_base = UNCORE_DISCOVERY_MSR,
+ .domain[0].global_init = uncore_mmio_global_init,
};
static const struct uncore_plat_init icx_uncore_init __initconst = {
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index 807e582b8f17..c663b00b68fe 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -245,6 +245,17 @@
#define MTL_UNC_HBO_CTR 0x2048
#define MTL_UNC_HBO_CTRL 0x2042
+/* PTL Low Power Bridge register */
+#define PTL_UNC_IA_CORE_BRIDGE_PER_CTR0 0x2028
+#define PTL_UNC_IA_CORE_BRIDGE_PERFEVTSEL0 0x2022
+
+/* PTL Santa register */
+#define PTL_UNC_SANTA_CTR0 0x2418
+#define PTL_UNC_SANTA_CTRL0 0x2412
+
+/* PTL cNCU register */
+#define PTL_UNC_CNCU_MSR_OFFSET 0x140
+
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
@@ -1921,8 +1932,36 @@ void ptl_uncore_mmio_init(void)
ptl_uncores);
}
+static struct intel_uncore_type ptl_uncore_ia_core_bridge = {
+ .name = "ia_core_bridge",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .perf_ctr = PTL_UNC_IA_CORE_BRIDGE_PER_CTR0,
+ .event_ctl = PTL_UNC_IA_CORE_BRIDGE_PERFEVTSEL0,
+ .event_mask = ADL_UNC_RAW_EVENT_MASK,
+ .ops = &icl_uncore_msr_ops,
+ .format_group = &adl_uncore_format_group,
+};
+
+static struct intel_uncore_type ptl_uncore_santa = {
+ .name = "santa",
+ .num_counters = 2,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .perf_ctr = PTL_UNC_SANTA_CTR0,
+ .event_ctl = PTL_UNC_SANTA_CTRL0,
+ .event_mask = ADL_UNC_RAW_EVENT_MASK,
+ .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
+ .ops = &icl_uncore_msr_ops,
+ .format_group = &adl_uncore_format_group,
+};
+
static struct intel_uncore_type *ptl_msr_uncores[] = {
&mtl_uncore_cbox,
+ &ptl_uncore_ia_core_bridge,
+ &ptl_uncore_santa,
+ &mtl_uncore_cncu,
NULL
};
@@ -1930,6 +1969,12 @@ void ptl_uncore_cpu_init(void)
{
mtl_uncore_cbox.num_boxes = 6;
mtl_uncore_cbox.ops = &lnl_uncore_msr_ops;
+
+ mtl_uncore_cncu.num_counters = 2;
+ mtl_uncore_cncu.num_boxes = 2;
+ mtl_uncore_cncu.msr_offset = PTL_UNC_CNCU_MSR_OFFSET;
+ mtl_uncore_cncu.single_fixed = 0;
+
uncore_msr_uncores = ptl_msr_uncores;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 12/13] perf/x86/intel/uncore: Add missing PMON units for Panther Lake
2025-12-31 22:42 ` [PATCH V2 12/13] perf/x86/intel/uncore: Add missing PMON units for Panther Lake Zide Chen
@ 2026-01-04 2:48 ` Mi, Dapeng
2026-01-04 2:49 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2 siblings, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:48 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> Besides CBOX, Panther Lake includes several legacy uncore PMON units
> not enumerated via discovery tables, including cNCU, SANTA, and
> ia_core_bridge.
>
> The cNCU PMON is similar to Meteor Lake but has two boxes with two
> counters each. SANTA and IA Core Bridge PMON units follow the legacy
> model used on Lunar Lake, Meteor Lake, and others.
>
> Panther Lake implements the Global Control Register; the freeze_all bit
> must be cleared before programming counters.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2: new patch
>
> arch/x86/events/intel/uncore.c | 1 +
> arch/x86/events/intel/uncore_snb.c | 45 ++++++++++++++++++++++++++++++
> 2 files changed, 46 insertions(+)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 54b3c1e3af32..07a9a2826398 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -1814,6 +1814,7 @@ static const struct uncore_plat_init ptl_uncore_init __initconst = {
> .cpu_init = ptl_uncore_cpu_init,
> .mmio_init = ptl_uncore_mmio_init,
> .domain[0].discovery_base = UNCORE_DISCOVERY_MSR,
> + .domain[0].global_init = uncore_mmio_global_init,
> };
>
> static const struct uncore_plat_init icx_uncore_init __initconst = {
> diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
> index 807e582b8f17..c663b00b68fe 100644
> --- a/arch/x86/events/intel/uncore_snb.c
> +++ b/arch/x86/events/intel/uncore_snb.c
> @@ -245,6 +245,17 @@
> #define MTL_UNC_HBO_CTR 0x2048
> #define MTL_UNC_HBO_CTRL 0x2042
>
> +/* PTL Low Power Bridge register */
> +#define PTL_UNC_IA_CORE_BRIDGE_PER_CTR0 0x2028
> +#define PTL_UNC_IA_CORE_BRIDGE_PERFEVTSEL0 0x2022
> +
> +/* PTL Santa register */
> +#define PTL_UNC_SANTA_CTR0 0x2418
> +#define PTL_UNC_SANTA_CTRL0 0x2412
> +
> +/* PTL cNCU register */
> +#define PTL_UNC_CNCU_MSR_OFFSET 0x140
> +
> DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
> DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
> DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
> @@ -1921,8 +1932,36 @@ void ptl_uncore_mmio_init(void)
> ptl_uncores);
> }
>
> +static struct intel_uncore_type ptl_uncore_ia_core_bridge = {
> + .name = "ia_core_bridge",
> + .num_counters = 2,
> + .num_boxes = 1,
> + .perf_ctr_bits = 48,
> + .perf_ctr = PTL_UNC_IA_CORE_BRIDGE_PER_CTR0,
> + .event_ctl = PTL_UNC_IA_CORE_BRIDGE_PERFEVTSEL0,
> + .event_mask = ADL_UNC_RAW_EVENT_MASK,
> + .ops = &icl_uncore_msr_ops,
> + .format_group = &adl_uncore_format_group,
> +};
> +
> +static struct intel_uncore_type ptl_uncore_santa = {
> + .name = "santa",
> + .num_counters = 2,
> + .num_boxes = 2,
> + .perf_ctr_bits = 48,
> + .perf_ctr = PTL_UNC_SANTA_CTR0,
> + .event_ctl = PTL_UNC_SANTA_CTRL0,
> + .event_mask = ADL_UNC_RAW_EVENT_MASK,
> + .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
> + .ops = &icl_uncore_msr_ops,
> + .format_group = &adl_uncore_format_group,
> +};
> +
> static struct intel_uncore_type *ptl_msr_uncores[] = {
> &mtl_uncore_cbox,
> + &ptl_uncore_ia_core_bridge,
> + &ptl_uncore_santa,
> + &mtl_uncore_cncu,
> NULL
> };
>
> @@ -1930,6 +1969,12 @@ void ptl_uncore_cpu_init(void)
> {
> mtl_uncore_cbox.num_boxes = 6;
> mtl_uncore_cbox.ops = &lnl_uncore_msr_ops;
> +
> + mtl_uncore_cncu.num_counters = 2;
> + mtl_uncore_cncu.num_boxes = 2;
> + mtl_uncore_cncu.msr_offset = PTL_UNC_CNCU_MSR_OFFSET;
> + mtl_uncore_cncu.single_fixed = 0;
> +
> uncore_msr_uncores = ptl_msr_uncores;
> }
>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 12/13] perf/x86/intel/uncore: Add missing PMON units for Panther Lake
2025-12-31 22:42 ` [PATCH V2 12/13] perf/x86/intel/uncore: Add missing PMON units for Panther Lake Zide Chen
2026-01-04 2:48 ` Mi, Dapeng
@ 2026-01-04 2:49 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2 siblings, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:49 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> Besides CBOX, Panther Lake includes several legacy uncore PMON units
> not enumerated via discovery tables, including cNCU, SANTA, and
> ia_core_bridge.
>
> The cNCU PMON is similar to Meteor Lake but has two boxes with two
> counters each. SANTA and IA Core Bridge PMON units follow the legacy
> model used on Lunar Lake, Meteor Lake, and others.
>
> Panther Lake implements the Global Control Register; the freeze_all bit
> must be cleared before programming counters.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2: new patch
>
> arch/x86/events/intel/uncore.c | 1 +
> arch/x86/events/intel/uncore_snb.c | 45 ++++++++++++++++++++++++++++++
> 2 files changed, 46 insertions(+)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 54b3c1e3af32..07a9a2826398 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -1814,6 +1814,7 @@ static const struct uncore_plat_init ptl_uncore_init __initconst = {
> .cpu_init = ptl_uncore_cpu_init,
> .mmio_init = ptl_uncore_mmio_init,
> .domain[0].discovery_base = UNCORE_DISCOVERY_MSR,
> + .domain[0].global_init = uncore_mmio_global_init,
> };
>
> static const struct uncore_plat_init icx_uncore_init __initconst = {
> diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
> index 807e582b8f17..c663b00b68fe 100644
> --- a/arch/x86/events/intel/uncore_snb.c
> +++ b/arch/x86/events/intel/uncore_snb.c
> @@ -245,6 +245,17 @@
> #define MTL_UNC_HBO_CTR 0x2048
> #define MTL_UNC_HBO_CTRL 0x2042
>
> +/* PTL Low Power Bridge register */
> +#define PTL_UNC_IA_CORE_BRIDGE_PER_CTR0 0x2028
> +#define PTL_UNC_IA_CORE_BRIDGE_PERFEVTSEL0 0x2022
> +
> +/* PTL Santa register */
> +#define PTL_UNC_SANTA_CTR0 0x2418
> +#define PTL_UNC_SANTA_CTRL0 0x2412
> +
> +/* PTL cNCU register */
> +#define PTL_UNC_CNCU_MSR_OFFSET 0x140
> +
> DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
> DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
> DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
> @@ -1921,8 +1932,36 @@ void ptl_uncore_mmio_init(void)
> ptl_uncores);
> }
>
> +static struct intel_uncore_type ptl_uncore_ia_core_bridge = {
> + .name = "ia_core_bridge",
> + .num_counters = 2,
> + .num_boxes = 1,
> + .perf_ctr_bits = 48,
> + .perf_ctr = PTL_UNC_IA_CORE_BRIDGE_PER_CTR0,
> + .event_ctl = PTL_UNC_IA_CORE_BRIDGE_PERFEVTSEL0,
> + .event_mask = ADL_UNC_RAW_EVENT_MASK,
> + .ops = &icl_uncore_msr_ops,
> + .format_group = &adl_uncore_format_group,
> +};
> +
> +static struct intel_uncore_type ptl_uncore_santa = {
> + .name = "santa",
> + .num_counters = 2,
> + .num_boxes = 2,
> + .perf_ctr_bits = 48,
> + .perf_ctr = PTL_UNC_SANTA_CTR0,
> + .event_ctl = PTL_UNC_SANTA_CTRL0,
> + .event_mask = ADL_UNC_RAW_EVENT_MASK,
> + .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
> + .ops = &icl_uncore_msr_ops,
> + .format_group = &adl_uncore_format_group,
> +};
> +
> static struct intel_uncore_type *ptl_msr_uncores[] = {
> &mtl_uncore_cbox,
> + &ptl_uncore_ia_core_bridge,
> + &ptl_uncore_santa,
> + &mtl_uncore_cncu,
> NULL
> };
>
> @@ -1930,6 +1969,12 @@ void ptl_uncore_cpu_init(void)
> {
> mtl_uncore_cbox.num_boxes = 6;
> mtl_uncore_cbox.ops = &lnl_uncore_msr_ops;
> +
> + mtl_uncore_cncu.num_counters = 2;
> + mtl_uncore_cncu.num_boxes = 2;
> + mtl_uncore_cncu.msr_offset = PTL_UNC_CNCU_MSR_OFFSET;
> + mtl_uncore_cncu.single_fixed = 0;
> +
> uncore_msr_uncores = ptl_msr_uncores;
> }
>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Add missing PMON units for Panther Lake
2025-12-31 22:42 ` [PATCH V2 12/13] perf/x86/intel/uncore: Add missing PMON units for Panther Lake Zide Chen
2026-01-04 2:48 ` Mi, Dapeng
2026-01-04 2:49 ` Mi, Dapeng
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
2 siblings, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 46da08a2bb4d07874990579235ff87b41911a412
Gitweb: https://git.kernel.org/tip/46da08a2bb4d07874990579235ff87b41911a412
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:29 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:26 +01:00
perf/x86/intel/uncore: Add missing PMON units for Panther Lake
Besides CBOX, Panther Lake includes several legacy uncore PMON units
not enumerated via discovery tables, including cNCU, SANTA, and
ia_core_bridge.
The cNCU PMON is similar to Meteor Lake but has two boxes with two
counters each. SANTA and IA Core Bridge PMON units follow the legacy
model used on Lunar Lake, Meteor Lake, and others.
Panther Lake implements the Global Control Register; the freeze_all bit
must be cleared before programming counters.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-13-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 1 +-
arch/x86/events/intel/uncore_snb.c | 45 +++++++++++++++++++++++++++++-
2 files changed, 46 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 19ff8db..704591a 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1814,6 +1814,7 @@ static const struct uncore_plat_init ptl_uncore_init __initconst = {
.cpu_init = ptl_uncore_cpu_init,
.mmio_init = ptl_uncore_mmio_init,
.domain[0].discovery_base = UNCORE_DISCOVERY_MSR,
+ .domain[0].global_init = uncore_mmio_global_init,
};
static const struct uncore_plat_init icx_uncore_init __initconst = {
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index 807e582..c663b00 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -245,6 +245,17 @@
#define MTL_UNC_HBO_CTR 0x2048
#define MTL_UNC_HBO_CTRL 0x2042
+/* PTL Low Power Bridge register */
+#define PTL_UNC_IA_CORE_BRIDGE_PER_CTR0 0x2028
+#define PTL_UNC_IA_CORE_BRIDGE_PERFEVTSEL0 0x2022
+
+/* PTL Santa register */
+#define PTL_UNC_SANTA_CTR0 0x2418
+#define PTL_UNC_SANTA_CTRL0 0x2412
+
+/* PTL cNCU register */
+#define PTL_UNC_CNCU_MSR_OFFSET 0x140
+
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
@@ -1921,8 +1932,36 @@ void ptl_uncore_mmio_init(void)
ptl_uncores);
}
+static struct intel_uncore_type ptl_uncore_ia_core_bridge = {
+ .name = "ia_core_bridge",
+ .num_counters = 2,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .perf_ctr = PTL_UNC_IA_CORE_BRIDGE_PER_CTR0,
+ .event_ctl = PTL_UNC_IA_CORE_BRIDGE_PERFEVTSEL0,
+ .event_mask = ADL_UNC_RAW_EVENT_MASK,
+ .ops = &icl_uncore_msr_ops,
+ .format_group = &adl_uncore_format_group,
+};
+
+static struct intel_uncore_type ptl_uncore_santa = {
+ .name = "santa",
+ .num_counters = 2,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .perf_ctr = PTL_UNC_SANTA_CTR0,
+ .event_ctl = PTL_UNC_SANTA_CTRL0,
+ .event_mask = ADL_UNC_RAW_EVENT_MASK,
+ .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
+ .ops = &icl_uncore_msr_ops,
+ .format_group = &adl_uncore_format_group,
+};
+
static struct intel_uncore_type *ptl_msr_uncores[] = {
&mtl_uncore_cbox,
+ &ptl_uncore_ia_core_bridge,
+ &ptl_uncore_santa,
+ &mtl_uncore_cncu,
NULL
};
@@ -1930,6 +1969,12 @@ void ptl_uncore_cpu_init(void)
{
mtl_uncore_cbox.num_boxes = 6;
mtl_uncore_cbox.ops = &lnl_uncore_msr_ops;
+
+ mtl_uncore_cncu.num_counters = 2;
+ mtl_uncore_cncu.num_boxes = 2;
+ mtl_uncore_cncu.msr_offset = PTL_UNC_CNCU_MSR_OFFSET;
+ mtl_uncore_cncu.single_fixed = 0;
+
uncore_msr_uncores = ptl_msr_uncores;
}
^ permalink raw reply related [flat|nested] 51+ messages in thread
* [PATCH V2 13/13] perf/x86/intel/uncore: Add Nova Lake support
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (11 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 12/13] perf/x86/intel/uncore: Add missing PMON units for Panther Lake Zide Chen
@ 2025-12-31 22:42 ` Zide Chen
2026-01-04 2:51 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
2026-01-06 15:08 ` [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Peter Zijlstra
13 siblings, 2 replies; 51+ messages in thread
From: Zide Chen @ 2025-12-31 22:42 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen, Xudong Hao,
Falcon Thomas
Nova Lake uncore PMON largely follows Panther Lake and supports CBOX,
iMC, cNCU, SANTA, sNCU, and HBO units.
As with Panther Lake, CBOX, cNCU, and SANTA are not enumerated via
discovery tables. Their programming model matches Panther Lake, with
differences limited to MSR addresses and the number of boxes or counters
per box.
The remaining units are enumerated via discovery tables using a new
base MSR (0x711) and otherwise reuse the Panther Lake implementation.
Nova Lake also supports iMC free-running counters.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2: new patch
arch/x86/events/intel/uncore.c | 9 ++++++
arch/x86/events/intel/uncore.h | 1 +
arch/x86/events/intel/uncore_discovery.h | 2 ++
arch/x86/events/intel/uncore_snb.c | 40 ++++++++++++++++++++++++
4 files changed, 52 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 07a9a2826398..2607bf178658 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1817,6 +1817,13 @@ static const struct uncore_plat_init ptl_uncore_init __initconst = {
.domain[0].global_init = uncore_mmio_global_init,
};
+static const struct uncore_plat_init nvl_uncore_init __initconst = {
+ .cpu_init = nvl_uncore_cpu_init,
+ .mmio_init = ptl_uncore_mmio_init,
+ .domain[0].discovery_base = PACKAGE_UNCORE_DISCOVERY_MSR,
+ .domain[0].global_init = uncore_mmio_global_init,
+};
+
static const struct uncore_plat_init icx_uncore_init __initconst = {
.cpu_init = icx_uncore_cpu_init,
.pci_init = icx_uncore_pci_init,
@@ -1916,6 +1923,8 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_uncore_init),
X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &ptl_uncore_init),
X86_MATCH_VFM(INTEL_WILDCATLAKE_L, &ptl_uncore_init),
+ X86_MATCH_VFM(INTEL_NOVALAKE, &nvl_uncore_init),
+ X86_MATCH_VFM(INTEL_NOVALAKE_L, &nvl_uncore_init),
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_uncore_init),
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &spr_uncore_init),
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &gnr_uncore_init),
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 564cb26c4468..c35918c01afa 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -636,6 +636,7 @@ void adl_uncore_cpu_init(void);
void lnl_uncore_cpu_init(void);
void mtl_uncore_cpu_init(void);
void ptl_uncore_cpu_init(void);
+void nvl_uncore_cpu_init(void);
void tgl_uncore_mmio_init(void);
void tgl_l_uncore_mmio_init(void);
void adl_uncore_mmio_init(void);
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index 63b8f7634e42..e1330342b92e 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -4,6 +4,8 @@
#define UNCORE_DISCOVERY_MSR 0x201e
/* Base address of uncore perfmon discovery table for CBB domain */
#define CBB_UNCORE_DISCOVERY_MSR 0x710
+/* Base address of uncore perfmon discovery table for the package */
+#define PACKAGE_UNCORE_DISCOVERY_MSR 0x711
/* Generic device ID of a discovery table device */
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index c663b00b68fe..e8e44741200e 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -256,6 +256,19 @@
/* PTL cNCU register */
#define PTL_UNC_CNCU_MSR_OFFSET 0x140
+/* NVL cNCU register */
+#define NVL_UNC_CNCU_BOX_CTL 0x202e
+#define NVL_UNC_CNCU_FIXED_CTR 0x2028
+#define NVL_UNC_CNCU_FIXED_CTRL 0x2022
+
+/* NVL SANTA register */
+#define NVL_UNC_SANTA_CTR0 0x2048
+#define NVL_UNC_SANTA_CTRL0 0x2042
+
+/* NVL CBOX register */
+#define NVL_UNC_CBOX_PER_CTR0 0x2108
+#define NVL_UNC_CBOX_PERFEVTSEL0 0x2102
+
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
@@ -1979,3 +1992,30 @@ void ptl_uncore_cpu_init(void)
}
/* end of Panther Lake uncore support */
+
+/* Nova Lake uncore support */
+
+static struct intel_uncore_type *nvl_msr_uncores[] = {
+ &mtl_uncore_cbox,
+ &ptl_uncore_santa,
+ &mtl_uncore_cncu,
+ NULL
+};
+
+void nvl_uncore_cpu_init(void)
+{
+ mtl_uncore_cbox.num_boxes = 12;
+ mtl_uncore_cbox.perf_ctr = NVL_UNC_CBOX_PER_CTR0,
+ mtl_uncore_cbox.event_ctl = NVL_UNC_CBOX_PERFEVTSEL0,
+
+ ptl_uncore_santa.perf_ctr = NVL_UNC_SANTA_CTR0,
+ ptl_uncore_santa.event_ctl = NVL_UNC_SANTA_CTRL0,
+
+ mtl_uncore_cncu.box_ctl = NVL_UNC_CNCU_BOX_CTL;
+ mtl_uncore_cncu.fixed_ctr = NVL_UNC_CNCU_FIXED_CTR;
+ mtl_uncore_cncu.fixed_ctl = NVL_UNC_CNCU_FIXED_CTRL;
+
+ uncore_msr_uncores = nvl_msr_uncores;
+}
+
+/* end of Nova Lake uncore support */
--
2.52.0
^ permalink raw reply related [flat|nested] 51+ messages in thread* Re: [PATCH V2 13/13] perf/x86/intel/uncore: Add Nova Lake support
2025-12-31 22:42 ` [PATCH V2 13/13] perf/x86/intel/uncore: Add Nova Lake support Zide Chen
@ 2026-01-04 2:51 ` Mi, Dapeng
2026-01-12 8:03 ` [tip: perf/core] " tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: Mi, Dapeng @ 2026-01-04 2:51 UTC (permalink / raw)
To: Zide Chen, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
Andi Kleen, Eranian Stephane
Cc: linux-kernel, linux-perf-users, Xudong Hao, Falcon Thomas
On 1/1/2026 6:42 AM, Zide Chen wrote:
> Nova Lake uncore PMON largely follows Panther Lake and supports CBOX,
> iMC, cNCU, SANTA, sNCU, and HBO units.
>
> As with Panther Lake, CBOX, cNCU, and SANTA are not enumerated via
> discovery tables. Their programming model matches Panther Lake, with
> differences limited to MSR addresses and the number of boxes or counters
> per box.
>
> The remaining units are enumerated via discovery tables using a new
> base MSR (0x711) and otherwise reuse the Panther Lake implementation.
> Nova Lake also supports iMC free-running counters.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2: new patch
>
> arch/x86/events/intel/uncore.c | 9 ++++++
> arch/x86/events/intel/uncore.h | 1 +
> arch/x86/events/intel/uncore_discovery.h | 2 ++
> arch/x86/events/intel/uncore_snb.c | 40 ++++++++++++++++++++++++
> 4 files changed, 52 insertions(+)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 07a9a2826398..2607bf178658 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -1817,6 +1817,13 @@ static const struct uncore_plat_init ptl_uncore_init __initconst = {
> .domain[0].global_init = uncore_mmio_global_init,
> };
>
> +static const struct uncore_plat_init nvl_uncore_init __initconst = {
> + .cpu_init = nvl_uncore_cpu_init,
> + .mmio_init = ptl_uncore_mmio_init,
> + .domain[0].discovery_base = PACKAGE_UNCORE_DISCOVERY_MSR,
> + .domain[0].global_init = uncore_mmio_global_init,
> +};
> +
> static const struct uncore_plat_init icx_uncore_init __initconst = {
> .cpu_init = icx_uncore_cpu_init,
> .pci_init = icx_uncore_pci_init,
> @@ -1916,6 +1923,8 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
> X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_uncore_init),
> X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &ptl_uncore_init),
> X86_MATCH_VFM(INTEL_WILDCATLAKE_L, &ptl_uncore_init),
> + X86_MATCH_VFM(INTEL_NOVALAKE, &nvl_uncore_init),
> + X86_MATCH_VFM(INTEL_NOVALAKE_L, &nvl_uncore_init),
> X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_uncore_init),
> X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &spr_uncore_init),
> X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &gnr_uncore_init),
> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
> index 564cb26c4468..c35918c01afa 100644
> --- a/arch/x86/events/intel/uncore.h
> +++ b/arch/x86/events/intel/uncore.h
> @@ -636,6 +636,7 @@ void adl_uncore_cpu_init(void);
> void lnl_uncore_cpu_init(void);
> void mtl_uncore_cpu_init(void);
> void ptl_uncore_cpu_init(void);
> +void nvl_uncore_cpu_init(void);
> void tgl_uncore_mmio_init(void);
> void tgl_l_uncore_mmio_init(void);
> void adl_uncore_mmio_init(void);
> diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
> index 63b8f7634e42..e1330342b92e 100644
> --- a/arch/x86/events/intel/uncore_discovery.h
> +++ b/arch/x86/events/intel/uncore_discovery.h
> @@ -4,6 +4,8 @@
> #define UNCORE_DISCOVERY_MSR 0x201e
> /* Base address of uncore perfmon discovery table for CBB domain */
> #define CBB_UNCORE_DISCOVERY_MSR 0x710
> +/* Base address of uncore perfmon discovery table for the package */
> +#define PACKAGE_UNCORE_DISCOVERY_MSR 0x711
>
> /* Generic device ID of a discovery table device */
> #define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
> diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
> index c663b00b68fe..e8e44741200e 100644
> --- a/arch/x86/events/intel/uncore_snb.c
> +++ b/arch/x86/events/intel/uncore_snb.c
> @@ -256,6 +256,19 @@
> /* PTL cNCU register */
> #define PTL_UNC_CNCU_MSR_OFFSET 0x140
>
> +/* NVL cNCU register */
> +#define NVL_UNC_CNCU_BOX_CTL 0x202e
> +#define NVL_UNC_CNCU_FIXED_CTR 0x2028
> +#define NVL_UNC_CNCU_FIXED_CTRL 0x2022
> +
> +/* NVL SANTA register */
> +#define NVL_UNC_SANTA_CTR0 0x2048
> +#define NVL_UNC_SANTA_CTRL0 0x2042
> +
> +/* NVL CBOX register */
> +#define NVL_UNC_CBOX_PER_CTR0 0x2108
> +#define NVL_UNC_CBOX_PERFEVTSEL0 0x2102
> +
> DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
> DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
> DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
> @@ -1979,3 +1992,30 @@ void ptl_uncore_cpu_init(void)
> }
>
> /* end of Panther Lake uncore support */
> +
> +/* Nova Lake uncore support */
> +
> +static struct intel_uncore_type *nvl_msr_uncores[] = {
> + &mtl_uncore_cbox,
> + &ptl_uncore_santa,
> + &mtl_uncore_cncu,
> + NULL
> +};
> +
> +void nvl_uncore_cpu_init(void)
> +{
> + mtl_uncore_cbox.num_boxes = 12;
> + mtl_uncore_cbox.perf_ctr = NVL_UNC_CBOX_PER_CTR0,
> + mtl_uncore_cbox.event_ctl = NVL_UNC_CBOX_PERFEVTSEL0,
> +
> + ptl_uncore_santa.perf_ctr = NVL_UNC_SANTA_CTR0,
> + ptl_uncore_santa.event_ctl = NVL_UNC_SANTA_CTRL0,
> +
> + mtl_uncore_cncu.box_ctl = NVL_UNC_CNCU_BOX_CTL;
> + mtl_uncore_cncu.fixed_ctr = NVL_UNC_CNCU_FIXED_CTR;
> + mtl_uncore_cncu.fixed_ctl = NVL_UNC_CNCU_FIXED_CTRL;
> +
> + uncore_msr_uncores = nvl_msr_uncores;
> +}
> +
> +/* end of Nova Lake uncore support */
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread* [tip: perf/core] perf/x86/intel/uncore: Add Nova Lake support
2025-12-31 22:42 ` [PATCH V2 13/13] perf/x86/intel/uncore: Add Nova Lake support Zide Chen
2026-01-04 2:51 ` Mi, Dapeng
@ 2026-01-12 8:03 ` tip-bot2 for Zide Chen
1 sibling, 0 replies; 51+ messages in thread
From: tip-bot2 for Zide Chen @ 2026-01-12 8:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: Zide Chen, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: e7d5f2ea0923c5e49ccf94cdaab74a08c865115e
Gitweb: https://git.kernel.org/tip/e7d5f2ea0923c5e49ccf94cdaab74a08c865115e
Author: Zide Chen <zide.chen@intel.com>
AuthorDate: Wed, 31 Dec 2025 14:42:30 -08:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 06 Jan 2026 16:34:26 +01:00
perf/x86/intel/uncore: Add Nova Lake support
Nova Lake uncore PMON largely follows Panther Lake and supports CBOX,
iMC, cNCU, SANTA, sNCU, and HBO units.
As with Panther Lake, CBOX, cNCU, and SANTA are not enumerated via
discovery tables. Their programming model matches Panther Lake, with
differences limited to MSR addresses and the number of boxes or counters
per box.
The remaining units are enumerated via discovery tables using a new
base MSR (0x711) and otherwise reuse the Panther Lake implementation.
Nova Lake also supports iMC free-running counters.
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20251231224233.113839-14-zide.chen@intel.com
---
arch/x86/events/intel/uncore.c | 9 +++++-
arch/x86/events/intel/uncore.h | 1 +-
arch/x86/events/intel/uncore_discovery.h | 2 +-
arch/x86/events/intel/uncore_snb.c | 40 +++++++++++++++++++++++-
4 files changed, 52 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 704591a..4684649 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1817,6 +1817,13 @@ static const struct uncore_plat_init ptl_uncore_init __initconst = {
.domain[0].global_init = uncore_mmio_global_init,
};
+static const struct uncore_plat_init nvl_uncore_init __initconst = {
+ .cpu_init = nvl_uncore_cpu_init,
+ .mmio_init = ptl_uncore_mmio_init,
+ .domain[0].discovery_base = PACKAGE_UNCORE_DISCOVERY_MSR,
+ .domain[0].global_init = uncore_mmio_global_init,
+};
+
static const struct uncore_plat_init icx_uncore_init __initconst = {
.cpu_init = icx_uncore_cpu_init,
.pci_init = icx_uncore_pci_init,
@@ -1916,6 +1923,8 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_uncore_init),
X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &ptl_uncore_init),
X86_MATCH_VFM(INTEL_WILDCATLAKE_L, &ptl_uncore_init),
+ X86_MATCH_VFM(INTEL_NOVALAKE, &nvl_uncore_init),
+ X86_MATCH_VFM(INTEL_NOVALAKE_L, &nvl_uncore_init),
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_uncore_init),
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &spr_uncore_init),
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &gnr_uncore_init),
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 564cb26..c35918c 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -636,6 +636,7 @@ void adl_uncore_cpu_init(void);
void lnl_uncore_cpu_init(void);
void mtl_uncore_cpu_init(void);
void ptl_uncore_cpu_init(void);
+void nvl_uncore_cpu_init(void);
void tgl_uncore_mmio_init(void);
void tgl_l_uncore_mmio_init(void);
void adl_uncore_mmio_init(void);
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index 63b8f76..e133034 100644
--- a/arch/x86/events/intel/uncore_discovery.h
+++ b/arch/x86/events/intel/uncore_discovery.h
@@ -4,6 +4,8 @@
#define UNCORE_DISCOVERY_MSR 0x201e
/* Base address of uncore perfmon discovery table for CBB domain */
#define CBB_UNCORE_DISCOVERY_MSR 0x710
+/* Base address of uncore perfmon discovery table for the package */
+#define PACKAGE_UNCORE_DISCOVERY_MSR 0x711
/* Generic device ID of a discovery table device */
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index c663b00..e8e4474 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -256,6 +256,19 @@
/* PTL cNCU register */
#define PTL_UNC_CNCU_MSR_OFFSET 0x140
+/* NVL cNCU register */
+#define NVL_UNC_CNCU_BOX_CTL 0x202e
+#define NVL_UNC_CNCU_FIXED_CTR 0x2028
+#define NVL_UNC_CNCU_FIXED_CTRL 0x2022
+
+/* NVL SANTA register */
+#define NVL_UNC_SANTA_CTR0 0x2048
+#define NVL_UNC_SANTA_CTRL0 0x2042
+
+/* NVL CBOX register */
+#define NVL_UNC_CBOX_PER_CTR0 0x2108
+#define NVL_UNC_CBOX_PERFEVTSEL0 0x2102
+
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11");
@@ -1979,3 +1992,30 @@ void ptl_uncore_cpu_init(void)
}
/* end of Panther Lake uncore support */
+
+/* Nova Lake uncore support */
+
+static struct intel_uncore_type *nvl_msr_uncores[] = {
+ &mtl_uncore_cbox,
+ &ptl_uncore_santa,
+ &mtl_uncore_cncu,
+ NULL
+};
+
+void nvl_uncore_cpu_init(void)
+{
+ mtl_uncore_cbox.num_boxes = 12;
+ mtl_uncore_cbox.perf_ctr = NVL_UNC_CBOX_PER_CTR0,
+ mtl_uncore_cbox.event_ctl = NVL_UNC_CBOX_PERFEVTSEL0,
+
+ ptl_uncore_santa.perf_ctr = NVL_UNC_SANTA_CTR0,
+ ptl_uncore_santa.event_ctl = NVL_UNC_SANTA_CTRL0,
+
+ mtl_uncore_cncu.box_ctl = NVL_UNC_CNCU_BOX_CTL;
+ mtl_uncore_cncu.fixed_ctr = NVL_UNC_CNCU_FIXED_CTR;
+ mtl_uncore_cncu.fixed_ctl = NVL_UNC_CNCU_FIXED_CTRL;
+
+ uncore_msr_uncores = nvl_msr_uncores;
+}
+
+/* end of Nova Lake uncore support */
^ permalink raw reply related [flat|nested] 51+ messages in thread
* Re: [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support
2025-12-31 22:42 [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Zide Chen
` (12 preceding siblings ...)
2025-12-31 22:42 ` [PATCH V2 13/13] perf/x86/intel/uncore: Add Nova Lake support Zide Chen
@ 2026-01-06 15:08 ` Peter Zijlstra
2026-01-06 21:19 ` Chen, Zide
13 siblings, 1 reply; 51+ messages in thread
From: Peter Zijlstra @ 2026-01-06 15:08 UTC (permalink / raw)
To: Zide Chen
Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Ian Rogers,
Adrian Hunter, Alexander Shishkin, Andi Kleen, Eranian Stephane,
linux-kernel, linux-perf-users, Dapeng Mi, Xudong Hao,
Falcon Thomas
On Wed, Dec 31, 2025 at 02:42:17PM -0800, Zide Chen wrote:
> Zide Chen (13):
> perf/x86/intel/uncore: Move uncore discovery init struct to header
> perf/x86/intel/uncore: Support per-platform discovery base devices
> perf/x86/intel/uncore: Remove has_generic_discovery_table()
> perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids
> perf/x86/intel/uncore: Add CBB PMON support for Diamond Rapids
> perf/x86/intel/uncore: Add domain global init callback
> perf/x86/intel/uncore: Add freerunning event descriptor helper macro
> perf/x86/intel/uncore: Support IIO free-running counters on DMR
> perf/x86/intel/uncore: Support uncore constraint ranges
> perf/x86/intel/uncore: Update DMR uncore constraints preliminarily
> perf pmu: Relax uncore wildcard matching to allow numeric suffix
> perf/x86/intel/uncore: Add missing PMON units for Panther Lake
> perf/x86/intel/uncore: Add Nova Lake support
Thanks, pushed out to queue/perf/core for the robots to have a go.
I made a few minor edits, the biggest of which I already shared in a
reply.
^ permalink raw reply [flat|nested] 51+ messages in thread* Re: [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support
2026-01-06 15:08 ` [PATCH V2 00/13] Add DMR/NVL and missing PTL uncore support Peter Zijlstra
@ 2026-01-06 21:19 ` Chen, Zide
0 siblings, 0 replies; 51+ messages in thread
From: Chen, Zide @ 2026-01-06 21:19 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Ian Rogers,
Adrian Hunter, Alexander Shishkin, Andi Kleen, Eranian Stephane,
linux-kernel, linux-perf-users, Dapeng Mi, Xudong Hao,
Falcon Thomas
On 1/6/2026 7:08 AM, Peter Zijlstra wrote:
> On Wed, Dec 31, 2025 at 02:42:17PM -0800, Zide Chen wrote:
>
>> Zide Chen (13):
>> perf/x86/intel/uncore: Move uncore discovery init struct to header
>> perf/x86/intel/uncore: Support per-platform discovery base devices
>> perf/x86/intel/uncore: Remove has_generic_discovery_table()
>> perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids
>> perf/x86/intel/uncore: Add CBB PMON support for Diamond Rapids
>> perf/x86/intel/uncore: Add domain global init callback
>> perf/x86/intel/uncore: Add freerunning event descriptor helper macro
>> perf/x86/intel/uncore: Support IIO free-running counters on DMR
>> perf/x86/intel/uncore: Support uncore constraint ranges
>> perf/x86/intel/uncore: Update DMR uncore constraints preliminarily
>> perf pmu: Relax uncore wildcard matching to allow numeric suffix
>> perf/x86/intel/uncore: Add missing PMON units for Panther Lake
>> perf/x86/intel/uncore: Add Nova Lake support
>
> Thanks, pushed out to queue/perf/core for the robots to have a go.
>
> I made a few minor edits, the biggest of which I already shared in a
> reply.
Thank you very much!
^ permalink raw reply [flat|nested] 51+ messages in thread