* [PATCH 1/7] perf/x86/intel/uncore: Add dual PCI/MSR discovery support
2025-12-12 21:00 [PATCH 0/7] Add Diamond Rapids uncore support Zide Chen
@ 2025-12-12 21:00 ` Zide Chen
2025-12-12 21:00 ` [PATCH 2/7] perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids Zide Chen
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Zide Chen @ 2025-12-12 21:00 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 a PCI device,
while CBB tables are enumerated via an MSR. This differs from prior
CPUs, which relied exclusively on either PCI or MSR.
Extend intel_uncore_has_discovery_tables() to support platforms that
require discovery through both PCI and MSR.
DMR CBB uncore uses MSR 0x710 for discovery instead of MSR 0x201e.
Introduce a discovery_msr field to store platform-specific MSR values.
Similarly, add a discovery_pci field so that DMR can enumerate through
PCI device 0x9a1 rather than 0x9a7.
In the !x86_match_cpu() fallback path, has_generic_discovery_table()
is removed because it does not consider multiple possible PCI devices
and its performance is not important here. Only probe MSR 0x201e to
keep the code simple.
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>
---
arch/x86/events/intel/uncore.c | 30 ++++++++++++-----
arch/x86/events/intel/uncore_discovery.c | 42 +++++++-----------------
arch/x86/events/intel/uncore_discovery.h | 2 +-
3 files changed, 34 insertions(+), 40 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index a762f7f5b161..ecf500470f8e 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1703,8 +1703,10 @@ struct intel_uncore_init_fun {
void (*cpu_init)(void);
int (*pci_init)(void);
void (*mmio_init)(void);
- /* Discovery table is required */
- bool use_discovery;
+ /* MSR carries the Discovery table base address */
+ u32 discovery_msr;
+ /* PCI device carries the Discovery table base address */
+ u32 discovery_pci;
/* The units in the discovery table should be ignored. */
int *uncore_units_ignore;
};
@@ -1810,7 +1812,7 @@ static const struct intel_uncore_init_fun lnl_uncore_init __initconst = {
static const struct intel_uncore_init_fun ptl_uncore_init __initconst = {
.cpu_init = ptl_uncore_cpu_init,
.mmio_init = ptl_uncore_mmio_init,
- .use_discovery = true,
+ .discovery_msr = UNCORE_DISCOVERY_MSR,
};
static const struct intel_uncore_init_fun icx_uncore_init __initconst = {
@@ -1829,7 +1831,7 @@ static const struct intel_uncore_init_fun 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,
+ .discovery_pci = UNCORE_DISCOVERY_TABLE_DEVICE,
.uncore_units_ignore = spr_uncore_units_ignore,
};
@@ -1837,7 +1839,7 @@ static const struct intel_uncore_init_fun 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,
+ .discovery_pci = UNCORE_DISCOVERY_TABLE_DEVICE,
.uncore_units_ignore = gnr_uncore_units_ignore,
};
@@ -1908,6 +1910,11 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
};
MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
+static bool ucore_use_discovery(struct intel_uncore_init_fun *uncore_init)
+{
+ return (uncore_init->discovery_pci || uncore_init->discovery_msr);
+}
+
static int __init intel_uncore_init(void)
{
const struct x86_cpu_id *id;
@@ -1922,16 +1929,21 @@ 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))
+ if (!uncore_no_discover &&
+ intel_uncore_has_discovery_tables(NULL,
+ UNCORE_DISCOVERY_MSR, PCI_ANY_ID))
uncore_init = (struct intel_uncore_init_fun *)&generic_uncore_init;
else
return -ENODEV;
} else {
uncore_init = (struct intel_uncore_init_fun *)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 &&
- !intel_uncore_has_discovery_tables(uncore_init->uncore_units_ignore))
+ if (ucore_use_discovery(uncore_init) &&
+ !intel_uncore_has_discovery_tables(
+ uncore_init->uncore_units_ignore,
+ uncore_init->discovery_msr,
+ uncore_init->discovery_pci))
return -ENODEV;
}
diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 7d57ce706feb..86373b00e966 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)
@@ -350,18 +332,13 @@ 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 intel_uncore_has_discovery_tables_pci(int *ignore, u32 device)
{
- u32 device, val, entry_id, bar_offset;
+ u32 val, entry_id, bar_offset;
int die, dvsec = 0, ret = true;
struct pci_dev *dev = NULL;
bool parsed = false;
- if (has_generic_discovery_table())
- device = UNCORE_DISCOVERY_TABLE_DEVICE;
- else
- device = PCI_ANY_ID;
-
/*
* Start a new search and iterates through the list of
* the discovery table devices.
@@ -399,7 +376,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 intel_uncore_has_discovery_tables_msr(int *ignore, u32 msr)
{
unsigned long *die_mask;
bool parsed = false;
@@ -417,7 +394,7 @@ static bool intel_uncore_has_discovery_tables_msr(int *ignore)
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)
@@ -432,10 +409,15 @@ static bool intel_uncore_has_discovery_tables_msr(int *ignore)
return parsed;
}
-bool intel_uncore_has_discovery_tables(int *ignore)
+bool intel_uncore_has_discovery_tables(int *ignore, u32 msr, u32 device)
{
- return intel_uncore_has_discovery_tables_msr(ignore) ||
- intel_uncore_has_discovery_tables_pci(ignore);
+ bool ret = false;
+
+ if (msr)
+ ret = intel_uncore_has_discovery_tables_msr(ignore, msr);
+ if (device)
+ ret |= intel_uncore_has_discovery_tables_pci(ignore, device);
+ return ret;
}
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..a919b1ac88fe 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 intel_uncore_has_discovery_tables(int *ignore, u32 msr, u32 device);
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] 8+ messages in thread* [PATCH 2/7] perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids
2025-12-12 21:00 [PATCH 0/7] Add Diamond Rapids uncore support Zide Chen
2025-12-12 21:00 ` [PATCH 1/7] perf/x86/intel/uncore: Add dual PCI/MSR discovery support Zide Chen
@ 2025-12-12 21:00 ` Zide Chen
2025-12-12 21:00 ` [PATCH 3/7] perf/x86/intel/uncore: Add CBB " Zide Chen
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Zide Chen @ 2025-12-12 21:00 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.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
arch/x86/events/intel/uncore.c | 8 +
arch/x86/events/intel/uncore.h | 3 +
arch/x86/events/intel/uncore_discovery.h | 2 +
arch/x86/events/intel/uncore_snbep.c | 228 +++++++++++++++++++++++
4 files changed, 241 insertions(+)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index ecf500470f8e..7ab02638e3f1 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1843,6 +1843,13 @@ 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 dmr_uncore_init __initconst = {
+ .pci_init = dmr_uncore_pci_init,
+ .mmio_init = dmr_uncore_mmio_init,
+ .discovery_pci = DMR_UNCORE_DISCOVERY_TABLE_DEVICE,
+ .uncore_units_ignore = dmr_uncore_units_ignore,
+};
+
static const struct intel_uncore_init_fun generic_uncore_init __initconst = {
.cpu_init = intel_uncore_generic_uncore_cpu_init,
.pci_init = intel_uncore_generic_uncore_pci_init,
@@ -1906,6 +1913,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 d8815fff7588..4f9c6e1e0c1a 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -597,6 +597,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_units_ignore[];
/* uncore_snb.c */
int snb_uncore_pci_init(void);
@@ -645,6 +646,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 a919b1ac88fe..786670276b5f 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..dee94bbdddcf 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,212 @@ 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_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_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] 8+ messages in thread* [PATCH 3/7] perf/x86/intel/uncore: Add CBB PMON support for Diamond Rapids
2025-12-12 21:00 [PATCH 0/7] Add Diamond Rapids uncore support Zide Chen
2025-12-12 21:00 ` [PATCH 1/7] perf/x86/intel/uncore: Add dual PCI/MSR discovery support Zide Chen
2025-12-12 21:00 ` [PATCH 2/7] perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids Zide Chen
@ 2025-12-12 21:00 ` Zide Chen
2025-12-12 21:00 ` [PATCH 4/7] perf/x86/intel/uncore: Add freerunning event descriptor helper macro Zide Chen
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Zide Chen @ 2025-12-12 21:00 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 PMON units for MSE and SB2UCIE.
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
arch/x86/events/intel/uncore.c | 1 +
arch/x86/events/intel/uncore_discovery.h | 2 +
arch/x86/events/intel/uncore_snbep.c | 48 ++++++++++++++++++++++--
3 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 7ab02638e3f1..88c32e528add 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1847,6 +1847,7 @@ static const struct intel_uncore_init_fun dmr_uncore_init __initconst = {
.pci_init = dmr_uncore_pci_init,
.mmio_init = dmr_uncore_mmio_init,
.discovery_pci = DMR_UNCORE_DISCOVERY_TABLE_DEVICE,
+ .discovery_msr = DMR_UNCORE_DISCOVERY_MSR,
.uncore_units_ignore = dmr_uncore_units_ignore,
};
diff --git a/arch/x86/events/intel/uncore_discovery.h b/arch/x86/events/intel/uncore_discovery.h
index 786670276b5f..a558c31ff2b1 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
+/* Alternative MSR that is used by server CPUs like DMR */
+#define DMR_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 dee94bbdddcf..bd1569876640 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -6806,6 +6806,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,
@@ -6813,6 +6835,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,
@@ -6901,10 +6937,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,
@@ -6919,6 +6960,7 @@ static struct intel_uncore_type *dmr_uncores[UNCORE_DMR_NUM_UNCORE_TYPES] = {
int dmr_uncore_units_ignore[] = {
0x13, /* MSE */
+ 0x25, /* SB2UCIE */
UNCORE_IGNORE_END
};
--
2.52.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/7] perf/x86/intel/uncore: Add freerunning event descriptor helper macro
2025-12-12 21:00 [PATCH 0/7] Add Diamond Rapids uncore support Zide Chen
` (2 preceding siblings ...)
2025-12-12 21:00 ` [PATCH 3/7] perf/x86/intel/uncore: Add CBB " Zide Chen
@ 2025-12-12 21:00 ` Zide Chen
2025-12-12 21:00 ` [PATCH 5/7] perf/x86/intel/uncore: Support IIO free-running counters on DMR Zide Chen
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Zide Chen @ 2025-12-12 21:00 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.
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 bd1569876640..56c6ac86f28e 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] 8+ messages in thread* [PATCH 5/7] perf/x86/intel/uncore: Support IIO free-running counters on DMR
2025-12-12 21:00 [PATCH 0/7] Add Diamond Rapids uncore support Zide Chen
` (3 preceding siblings ...)
2025-12-12 21:00 ` [PATCH 4/7] perf/x86/intel/uncore: Add freerunning event descriptor helper macro Zide Chen
@ 2025-12-12 21:00 ` Zide Chen
2025-12-12 21:00 ` [PATCH 6/7] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily Zide Chen
2025-12-12 21:00 ` [PATCH 7/7] perf pmu: Relax uncore wildcard matching to allow numeric suffix Zide Chen
6 siblings, 0 replies; 8+ messages in thread
From: Zide Chen @ 2025-12-12 21:00 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>
---
arch/x86/events/intel/uncore_snbep.c | 120 +++++++++++++++++++++++++--
1 file changed, 115 insertions(+), 5 deletions(-)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 56c6ac86f28e..21cca1b28075 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;
@@ -6925,6 +6933,103 @@ int dmr_uncore_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) {
+ pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
+ 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,
@@ -6932,11 +7037,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] 8+ messages in thread* [PATCH 6/7] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily
2025-12-12 21:00 [PATCH 0/7] Add Diamond Rapids uncore support Zide Chen
` (4 preceding siblings ...)
2025-12-12 21:00 ` [PATCH 5/7] perf/x86/intel/uncore: Support IIO free-running counters on DMR Zide Chen
@ 2025-12-12 21:00 ` Zide Chen
2025-12-12 21:00 ` [PATCH 7/7] perf pmu: Relax uncore wildcard matching to allow numeric suffix Zide Chen
6 siblings, 0 replies; 8+ messages in thread
From: Zide Chen @ 2025-12-12 21:00 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>
---
arch/x86/events/intel/uncore_snbep.c | 81 ++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index e5b95fa75313..8068b9404ecb 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -6760,10 +6760,72 @@ 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(0x1, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x2, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x3, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x4, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x5, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x6, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x7, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x8, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x9, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0xa, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0xb, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0xc, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0xd, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0xe, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0xf, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x10, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x11, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x12, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x14, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x1d, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x1e, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x1f, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x20, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x21, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x22, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x23, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x24, 0x0f),
+ UNCORE_EVENT_CONSTRAINT(0x41, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x42, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x43, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x44, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x45, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x46, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x47, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x48, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x49, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x4a, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x4b, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x4c, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x4e, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x50, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x51, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x52, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x53, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x54, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x55, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x56, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x57, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x58, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x59, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x5a, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x5b, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x5c, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x5d, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x5e, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(0x60, 0xf0),
+ UNCORE_EVENT_CONSTRAINT(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,
};
@@ -6775,9 +6837,21 @@ 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(0x19, 0x1),
+ UNCORE_EVENT_CONSTRAINT(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,
};
@@ -6811,9 +6885,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] 8+ messages in thread* [PATCH 7/7] perf pmu: Relax uncore wildcard matching to allow numeric suffix
2025-12-12 21:00 [PATCH 0/7] Add Diamond Rapids uncore support Zide Chen
` (5 preceding siblings ...)
2025-12-12 21:00 ` [PATCH 6/7] perf/x86/intel/uncore: Update DMR uncore constraints preliminarily Zide Chen
@ 2025-12-12 21:00 ` Zide Chen
6 siblings, 0 replies; 8+ messages in thread
From: Zide Chen @ 2025-12-12 21:00 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>
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 3d1f975e8db9..00cb72615621 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -905,6 +905,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. */
@@ -915,13 +916,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] 8+ messages in thread