The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems
@ 2026-05-27 15:11 Zide Chen
  2026-05-27 15:11 ` [PATCH V2 2/7] perf/x86/intel/uncore: Guard against invalid box control address Zide Chen
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Zide Chen @ 2026-05-27 15:11 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

In uncore_find_add_unit(), PMON units with the same unit ID may be
added to the uncore discovery RB-tree for different dies. These units
are distinguished by node->die.

However, intel_generic_uncore_box_ctl() uses a fixed die ID of -1 when
looking up the discovery unit, which may retrieve the wrong node on
multi-die systems.

Use box->dieid instead so the correct discovery unit is selected.

No functional issue has been observed so far because currently supported
platforms happen to use the same unit control register for such units.

Remove WARN_ON_ONCE() because with the above change a NULL unit can be
expected, e.g. when a CPU die is offline during uncore enumeration and
the unit is not added to the RB-tree. In this case,
intel_uncore_find_discovery_unit() returns NULL once the die becomes
online, and it is expected that the PMU box is not functional for that
die.

Fixes: b1d9ea2e1ca4 ("perf/x86/uncore: Apply the unit control RB tree to MSR uncore units")
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
v2:
- Remove WARN_ON_ONCE().
---
 arch/x86/events/intel/uncore_discovery.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 583cbd06b9b8..60e1200c4691 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -481,8 +481,8 @@ static u64 intel_generic_uncore_box_ctl(struct intel_uncore_box *box)
 	struct intel_uncore_discovery_unit *unit;
 
 	unit = intel_uncore_find_discovery_unit(box->pmu->type->boxes,
-						-1, box->pmu->pmu_idx);
-	if (WARN_ON_ONCE(!unit))
+						box->dieid, box->pmu->pmu_idx);
+	if (!unit)
 		return 0;
 
 	return unit->addr;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH V2 2/7] perf/x86/intel/uncore: Guard against invalid box control address
  2026-05-27 15:11 [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Zide Chen
@ 2026-05-27 15:11 ` Zide Chen
  2026-05-28  6:03   ` Mi, Dapeng
  2026-05-27 15:11 ` [PATCH V2 3/7] perf/x86/intel/uncore: Fix PCI device refcount leak in UPI discovery Zide Chen
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Zide Chen @ 2026-05-27 15:11 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

Theoretically, intel_uncore_find_discovery_unit() could return NULL,
e.g., when a CPU die is offline during uncore enumeration and its PMU
units are not added to the discovery RB-tree.

Guard against a NULL return value and the resulting invalid box control
address (0) before accessing hardware.

Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2:
- New patch.
- Address pre-existing invalid box control address issue (Sashiko).
---
 arch/x86/events/intel/uncore_discovery.c | 36 ++++++++++++++++++------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
index 60e1200c4691..af2217b44a81 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -490,17 +490,28 @@ static u64 intel_generic_uncore_box_ctl(struct intel_uncore_box *box)
 
 void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box)
 {
-	wrmsrq(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_INT);
+	u64 box_ctl = intel_generic_uncore_box_ctl(box);
+
+	if (!box_ctl)
+		return;
+
+	wrmsrq(box_ctl, GENERIC_PMON_BOX_CTL_INT);
 }
 
 void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box)
 {
-	wrmsrq(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_FRZ);
+	u64 box_ctl = intel_generic_uncore_box_ctl(box);
+
+	if (box_ctl)
+		wrmsrq(box_ctl, GENERIC_PMON_BOX_CTL_FRZ);
 }
 
 void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box)
 {
-	wrmsrq(intel_generic_uncore_box_ctl(box), 0);
+	u64 box_ctl = intel_generic_uncore_box_ctl(box);
+
+	if (box_ctl)
+		wrmsrq(box_ctl, 0);
 }
 
 static void intel_generic_uncore_msr_enable_event(struct intel_uncore_box *box,
@@ -549,6 +560,10 @@ bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
 
 	if (box->pci_dev) {
 		box_ctl = UNCORE_DISCOVERY_PCI_BOX_CTRL(box_ctl);
+
+		if (!box_ctl)
+			return false;
+
 		hwc->config_base = box_ctl + uncore_pci_event_ctl(box, hwc->idx);
 		hwc->event_base  = box_ctl + uncore_pci_perf_ctr(box, hwc->idx);
 		return true;
@@ -567,27 +582,30 @@ static inline int intel_pci_uncore_box_ctl(struct intel_uncore_box *box)
 
 void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box)
 {
-	struct pci_dev *pdev = box->pci_dev;
 	int box_ctl = intel_pci_uncore_box_ctl(box);
 
+	if (!box_ctl)
+		return;
+
 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
-	pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_INT);
+	pci_write_config_dword(box->pci_dev, box_ctl, GENERIC_PMON_BOX_CTL_INT);
 }
 
 void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box)
 {
-	struct pci_dev *pdev = box->pci_dev;
 	int box_ctl = intel_pci_uncore_box_ctl(box);
 
-	pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_FRZ);
+	if (box_ctl)
+		pci_write_config_dword(box->pci_dev, box_ctl,
+				       GENERIC_PMON_BOX_CTL_FRZ);
 }
 
 void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box)
 {
-	struct pci_dev *pdev = box->pci_dev;
 	int box_ctl = intel_pci_uncore_box_ctl(box);
 
-	pci_write_config_dword(pdev, box_ctl, 0);
+	if (box_ctl)
+		pci_write_config_dword(box->pci_dev, box_ctl, 0);
 }
 
 static void intel_generic_uncore_pci_enable_event(struct intel_uncore_box *box,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH V2 3/7] perf/x86/intel/uncore: Fix PCI device refcount leak in UPI discovery
  2026-05-27 15:11 [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Zide Chen
  2026-05-27 15:11 ` [PATCH V2 2/7] perf/x86/intel/uncore: Guard against invalid box control address Zide Chen
@ 2026-05-27 15:11 ` Zide Chen
  2026-05-28  6:34   ` Mi, Dapeng
  2026-05-27 15:11 ` [PATCH V2 4/7] perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box() Zide Chen
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Zide Chen @ 2026-05-27 15:11 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

pci_get_domain_bus_and_slot() increments the reference count of the
returned PCI device and therefore requires a matching pci_dev_put().

In skx_upi_topology_cb() and discover_upi_topology(), the lookup is
performed inside a loop, but pci_dev_put() is only called once after
the loop. As a result, references from all previous iterations are
leaked.

Move pci_dev_put(dev) into the if (dev) block immediately after
upi_fill_topology() returns.

Opportunistically, fix uninitialized variable in skx_upi_topology_cb().

Fixes: 4cfce57fa42d ("perf/x86/intel/uncore: Enable UPI topology discovery for Skylake Server")
Fixes: f680b6e6062e ("perf/x86/intel/uncore: Enable UPI topology discovery for Icelake Server")
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
 arch/x86/events/intel/uncore_snbep.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 215d33e260ed..c9ce206fcbb6 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -4261,7 +4261,7 @@ static int upi_fill_topology(struct pci_dev *dev, struct intel_uncore_topology *
 static int skx_upi_topology_cb(struct intel_uncore_type *type, int segment,
 				int die, u64 cpu_bus_msr)
 {
-	int idx, ret;
+	int idx, ret = 0;
 	struct intel_uncore_topology *upi;
 	unsigned int devfn;
 	struct pci_dev *dev = NULL;
@@ -4274,12 +4274,12 @@ static int skx_upi_topology_cb(struct intel_uncore_type *type, int segment,
 		dev = pci_get_domain_bus_and_slot(segment, bus, devfn);
 		if (dev) {
 			ret = upi_fill_topology(dev, upi, idx);
+			pci_dev_put(dev);
 			if (ret)
 				break;
 		}
 	}
 
-	pci_dev_put(dev);
 	return ret;
 }
 
@@ -5499,6 +5499,7 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i
 							  devfn);
 			if (dev) {
 				ret = upi_fill_topology(dev, upi, idx);
+				pci_dev_put(dev);
 				if (ret)
 					goto err;
 			}
@@ -5506,7 +5507,6 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i
 	}
 err:
 	pci_dev_put(ubox);
-	pci_dev_put(dev);
 	return ret;
 }
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH V2 4/7] perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box()
  2026-05-27 15:11 [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Zide Chen
  2026-05-27 15:11 ` [PATCH V2 2/7] perf/x86/intel/uncore: Guard against invalid box control address Zide Chen
  2026-05-27 15:11 ` [PATCH V2 3/7] perf/x86/intel/uncore: Fix PCI device refcount leak in UPI discovery Zide Chen
@ 2026-05-27 15:11 ` Zide Chen
  2026-05-28  6:35   ` Mi, Dapeng
  2026-05-27 15:11 ` [PATCH V2 5/7] perf/x86/intel/uncore: Move die_to_cpu() to uncore.c Zide Chen
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Zide Chen @ 2026-05-27 15:11 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, stable

On some Raptor Cove CPUs, enabling uncore PMON globally at driver init
may increase power consumption even when no perf events are in use.

Drop adl_uncore_msr_init_box() and defer programming the global control
register to enable_box(), so it is only set when a box is actually used.

IMC and IMC freerunning counters use a separate control path and are
unaffected.

Cc: stable@vger.kernel.org
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
 arch/x86/events/intel/uncore_snb.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index 3dbc6bacbd9d..edddd4f9ab5f 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -563,12 +563,6 @@ void tgl_uncore_cpu_init(void)
 	skl_uncore_msr_ops.init_box = rkl_uncore_msr_init_box;
 }
 
-static void adl_uncore_msr_init_box(struct intel_uncore_box *box)
-{
-	if (box->pmu->pmu_idx == 0)
-		wrmsrq(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
-}
-
 static void adl_uncore_msr_enable_box(struct intel_uncore_box *box)
 {
 	wrmsrq(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
@@ -587,7 +581,6 @@ static void adl_uncore_msr_exit_box(struct intel_uncore_box *box)
 }
 
 static struct intel_uncore_ops adl_uncore_msr_ops = {
-	.init_box	= adl_uncore_msr_init_box,
 	.enable_box	= adl_uncore_msr_enable_box,
 	.disable_box	= adl_uncore_msr_disable_box,
 	.exit_box	= adl_uncore_msr_exit_box,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH V2 5/7] perf/x86/intel/uncore: Move die_to_cpu() to uncore.c
  2026-05-27 15:11 [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Zide Chen
                   ` (2 preceding siblings ...)
  2026-05-27 15:11 ` [PATCH V2 4/7] perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box() Zide Chen
@ 2026-05-27 15:11 ` Zide Chen
  2026-05-28  6:36   ` Mi, Dapeng
  2026-05-29 10:54   ` Peter Zijlstra
  2026-05-27 15:11 ` [PATCH V2 6/7] perf/x86/intel/uncore: Fix uncore_die_to_cpu() for offline dies Zide Chen
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 20+ messages in thread
From: Zide Chen @ 2026-05-27 15:11 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

Move die_to_cpu() into uncore.c so it can be reused by the MSR
initialization path, preparing for the introduction of an MSR global
initialization callback.

Move the cpus_read_{lock,unlock}() out of the API, in order to make
it possible to be called when the lock is being held.

Add the uncore_ prefix for consistency with other uncore APIs.

Signed-off-by: Zide Chen <zide.chen@intel.com>

V2:
- Move cpus_read_{lock,unlock}() out of uncore_die_to_cpu() and rely
  on callers to manage the lock. (Sashiko)
- Remove "No functional change intended" from the changelog.
---
 arch/x86/events/intel/uncore.c       | 19 +++++++++++++++++++
 arch/x86/events/intel/uncore.h       |  1 +
 arch/x86/events/intel/uncore_snbep.c | 23 +++--------------------
 3 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index e9cc1ba921c5..22256ded2d67 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -83,6 +83,25 @@ int uncore_device_to_die(struct pci_dev *dev)
 	return -1;
 }
 
+/*
+ * Using cpus_read_lock() to ensure cpu is not going down between
+ * looking at cpu_online_mask.
+ *
+ * The lock must be held by the caller.
+ */
+int uncore_die_to_cpu(int die)
+{
+	int res = 0, cpu;
+
+	for_each_online_cpu(cpu) {
+		if (topology_logical_die_id(cpu) == die) {
+			res = cpu;
+			break;
+		}
+	}
+	return res;
+}
+
 static void uncore_free_pcibus_map(void)
 {
 	struct pci2phy_map *map, *tmp;
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index c35918c01afa..94c68e3417b6 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -235,6 +235,7 @@ struct pci2phy_map *__find_pci2phy_map(int segment);
 int uncore_pcibus_to_dieid(struct pci_bus *bus);
 int uncore_die_to_segment(int die);
 int uncore_device_to_die(struct pci_dev *dev);
+int uncore_die_to_cpu(int die);
 
 ssize_t uncore_event_show(struct device *dev,
 			  struct device_attribute *attr, char *buf);
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index c9ce206fcbb6..772b78237424 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -3704,25 +3704,6 @@ static int skx_msr_cpu_bus_read(int cpu, u64 *topology)
 	return 0;
 }
 
-static int die_to_cpu(int die)
-{
-	int res = 0, cpu, current_die;
-	/*
-	 * Using cpus_read_lock() to ensure cpu is not going down between
-	 * looking at cpu_online_mask.
-	 */
-	cpus_read_lock();
-	for_each_online_cpu(cpu) {
-		current_die = topology_logical_die_id(cpu);
-		if (current_die == die) {
-			res = cpu;
-			break;
-		}
-	}
-	cpus_read_unlock();
-	return res;
-}
-
 enum {
 	IIO_TOPOLOGY_TYPE,
 	UPI_TOPOLOGY_TYPE,
@@ -3794,8 +3775,9 @@ static int skx_pmu_get_topology(struct intel_uncore_type *type,
 	int die, ret = -EPERM;
 	u64 cpu_bus_msr;
 
+	cpus_read_lock();
 	for (die = 0; die < uncore_max_dies(); die++) {
-		ret = skx_msr_cpu_bus_read(die_to_cpu(die), &cpu_bus_msr);
+		ret = skx_msr_cpu_bus_read(uncore_die_to_cpu(die), &cpu_bus_msr);
 		if (ret)
 			break;
 
@@ -3807,6 +3789,7 @@ static int skx_pmu_get_topology(struct intel_uncore_type *type,
 		if (ret)
 			break;
 	}
+	cpus_read_unlock();
 
 	return ret;
 }
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH V2 6/7] perf/x86/intel/uncore: Fix uncore_die_to_cpu() for offline dies
  2026-05-27 15:11 [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Zide Chen
                   ` (3 preceding siblings ...)
  2026-05-27 15:11 ` [PATCH V2 5/7] perf/x86/intel/uncore: Move die_to_cpu() to uncore.c Zide Chen
@ 2026-05-27 15:11 ` Zide Chen
  2026-05-28  6:38   ` Mi, Dapeng
  2026-05-27 15:11 ` [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore Zide Chen
  2026-05-28  6:01 ` [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Mi, Dapeng
  6 siblings, 1 reply; 20+ messages in thread
From: Zide Chen @ 2026-05-27 15:11 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

If the die is offline when uncore_die_to_cpu() is called, it silently
returns 0, which is misleading.  Return -1 in this case to indicate
that all CPUs on the die are offline and the caller can take care of
it accordingly.

Opportunistically, replace -EPERM with -ENODEV, as -ENODEV is
the appropriate error when no CPUs are online across all dies.

Signed-off-by: Zide Chen <zide.chen@intel.com>
---
 arch/x86/events/intel/uncore.c       | 2 +-
 arch/x86/events/intel/uncore_snbep.c | 9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 22256ded2d67..4b3a1fa5b41b 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -91,7 +91,7 @@ int uncore_device_to_die(struct pci_dev *dev)
  */
 int uncore_die_to_cpu(int die)
 {
-	int res = 0, cpu;
+	int res = -1, cpu;
 
 	for_each_online_cpu(cpu) {
 		if (topology_logical_die_id(cpu) == die) {
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 772b78237424..334dc384b5b9 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -3772,12 +3772,17 @@ static void pmu_free_topology(struct intel_uncore_type *type)
 static int skx_pmu_get_topology(struct intel_uncore_type *type,
 				 int (*topology_cb)(struct intel_uncore_type*, int, int, u64))
 {
-	int die, ret = -EPERM;
+	int die, ret = -ENODEV;
 	u64 cpu_bus_msr;
+	int cpu;
 
 	cpus_read_lock();
 	for (die = 0; die < uncore_max_dies(); die++) {
-		ret = skx_msr_cpu_bus_read(uncore_die_to_cpu(die), &cpu_bus_msr);
+		cpu = uncore_die_to_cpu(die);
+		if (cpu == -1)
+			continue;
+
+		ret = skx_msr_cpu_bus_read(cpu, &cpu_bus_msr);
 		if (ret)
 			break;
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore
  2026-05-27 15:11 [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Zide Chen
                   ` (4 preceding siblings ...)
  2026-05-27 15:11 ` [PATCH V2 6/7] perf/x86/intel/uncore: Fix uncore_die_to_cpu() for offline dies Zide Chen
@ 2026-05-27 15:11 ` Zide Chen
  2026-05-28  6:46   ` Mi, Dapeng
  2026-05-28  6:01 ` [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Mi, Dapeng
  6 siblings, 1 reply; 20+ messages in thread
From: Zide Chen @ 2026-05-27 15:11 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

On Sierra Forest and Clearwater Forest, the FRZ_ALL bit in the global
control register defaults to 0 at boot, but UBOX PMON units do not
work until the global control register is explicitly written with 0
to trigger hardware initialization properly.

Implement the generic uncore_msr_global_init() callback and add it to
gnr_uncore_init[], which is shared by GNR, GRR, SRF, and CWF.

Signed-off-by: Zide Chen <zide.chen@intel.com>
---
V2:
- Propagate return value of wrmsrq_on_cpu() to global_init().
---
 arch/x86/events/intel/uncore.c           | 13 ++++++++++++-
 arch/x86/events/intel/uncore.h           |  2 +-
 arch/x86/events/intel/uncore_discovery.c |  2 +-
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 4b3a1fa5b41b..7857959c6e82 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1716,7 +1716,7 @@ static int __init uncore_mmio_init(void)
 	return ret;
 }
 
-static int uncore_mmio_global_init(u64 ctl)
+static int uncore_mmio_global_init(int die, u64 ctl)
 {
 	void __iomem *io_addr;
 
@@ -1731,6 +1731,16 @@ static int uncore_mmio_global_init(u64 ctl)
 	return 0;
 }
 
+static int uncore_msr_global_init(int die, u64 msr)
+{
+	int cpu = uncore_die_to_cpu(die);
+
+	if (cpu == -1)
+		return -ENODEV;
+
+	return wrmsrq_on_cpu(cpu, msr, 0);
+}
+
 static const struct uncore_plat_init nhm_uncore_init __initconst = {
 	.cpu_init = nhm_uncore_cpu_init,
 };
@@ -1871,6 +1881,7 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
 	.domain[0].base_is_pci = true,
 	.domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
 	.domain[0].units_ignore = gnr_uncore_units_ignore,
+	.domain[0].global_init = uncore_msr_global_init,
 };
 
 static const struct uncore_plat_init dmr_uncore_init __initconst = {
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 94c68e3417b6..c2e5ccb1d72c 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -53,7 +53,7 @@ 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);
+	int	(*global_init)(int die, 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 af2217b44a81..e36613d934b1 100644
--- a/arch/x86/events/intel/uncore_discovery.c
+++ b/arch/x86/events/intel/uncore_discovery.c
@@ -287,7 +287,7 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
 	if (!io_addr)
 		return -ENOMEM;
 
-	if (domain->global_init && domain->global_init(global.ctl)) {
+	if (domain->global_init && domain->global_init(die, global.ctl)) {
 		ret = -ENODEV;
 		goto out;
 	}
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems
  2026-05-27 15:11 [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Zide Chen
                   ` (5 preceding siblings ...)
  2026-05-27 15:11 ` [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore Zide Chen
@ 2026-05-28  6:01 ` Mi, Dapeng
  6 siblings, 0 replies; 20+ messages in thread
From: Mi, Dapeng @ 2026-05-28  6:01 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

LGTM.

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>

On 5/27/2026 11:11 PM, Zide Chen wrote:
> In uncore_find_add_unit(), PMON units with the same unit ID may be
> added to the uncore discovery RB-tree for different dies. These units
> are distinguished by node->die.
>
> However, intel_generic_uncore_box_ctl() uses a fixed die ID of -1 when
> looking up the discovery unit, which may retrieve the wrong node on
> multi-die systems.
>
> Use box->dieid instead so the correct discovery unit is selected.
>
> No functional issue has been observed so far because currently supported
> platforms happen to use the same unit control register for such units.
>
> Remove WARN_ON_ONCE() because with the above change a NULL unit can be
> expected, e.g. when a CPU die is offline during uncore enumeration and
> the unit is not added to the RB-tree. In this case,
> intel_uncore_find_discovery_unit() returns NULL once the die becomes
> online, and it is expected that the PMU box is not functional for that
> die.
>
> Fixes: b1d9ea2e1ca4 ("perf/x86/uncore: Apply the unit control RB tree to MSR uncore units")
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> v2:
> - Remove WARN_ON_ONCE().
> ---
>  arch/x86/events/intel/uncore_discovery.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
> index 583cbd06b9b8..60e1200c4691 100644
> --- a/arch/x86/events/intel/uncore_discovery.c
> +++ b/arch/x86/events/intel/uncore_discovery.c
> @@ -481,8 +481,8 @@ static u64 intel_generic_uncore_box_ctl(struct intel_uncore_box *box)
>  	struct intel_uncore_discovery_unit *unit;
>  
>  	unit = intel_uncore_find_discovery_unit(box->pmu->type->boxes,
> -						-1, box->pmu->pmu_idx);
> -	if (WARN_ON_ONCE(!unit))
> +						box->dieid, box->pmu->pmu_idx);
> +	if (!unit)
>  		return 0;
>  
>  	return unit->addr;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 2/7] perf/x86/intel/uncore: Guard against invalid box control address
  2026-05-27 15:11 ` [PATCH V2 2/7] perf/x86/intel/uncore: Guard against invalid box control address Zide Chen
@ 2026-05-28  6:03   ` Mi, Dapeng
  0 siblings, 0 replies; 20+ messages in thread
From: Mi, Dapeng @ 2026-05-28  6: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

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>


On 5/27/2026 11:11 PM, Zide Chen wrote:
> Theoretically, intel_uncore_find_discovery_unit() could return NULL,
> e.g., when a CPU die is offline during uncore enumeration and its PMU
> units are not added to the discovery RB-tree.
>
> Guard against a NULL return value and the resulting invalid box control
> address (0) before accessing hardware.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2:
> - New patch.
> - Address pre-existing invalid box control address issue (Sashiko).
> ---
>  arch/x86/events/intel/uncore_discovery.c | 36 ++++++++++++++++++------
>  1 file changed, 27 insertions(+), 9 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c
> index 60e1200c4691..af2217b44a81 100644
> --- a/arch/x86/events/intel/uncore_discovery.c
> +++ b/arch/x86/events/intel/uncore_discovery.c
> @@ -490,17 +490,28 @@ static u64 intel_generic_uncore_box_ctl(struct intel_uncore_box *box)
>  
>  void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box)
>  {
> -	wrmsrq(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_INT);
> +	u64 box_ctl = intel_generic_uncore_box_ctl(box);
> +
> +	if (!box_ctl)
> +		return;
> +
> +	wrmsrq(box_ctl, GENERIC_PMON_BOX_CTL_INT);
>  }
>  
>  void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box)
>  {
> -	wrmsrq(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_FRZ);
> +	u64 box_ctl = intel_generic_uncore_box_ctl(box);
> +
> +	if (box_ctl)
> +		wrmsrq(box_ctl, GENERIC_PMON_BOX_CTL_FRZ);
>  }
>  
>  void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box)
>  {
> -	wrmsrq(intel_generic_uncore_box_ctl(box), 0);
> +	u64 box_ctl = intel_generic_uncore_box_ctl(box);
> +
> +	if (box_ctl)
> +		wrmsrq(box_ctl, 0);
>  }
>  
>  static void intel_generic_uncore_msr_enable_event(struct intel_uncore_box *box,
> @@ -549,6 +560,10 @@ bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
>  
>  	if (box->pci_dev) {
>  		box_ctl = UNCORE_DISCOVERY_PCI_BOX_CTRL(box_ctl);
> +
> +		if (!box_ctl)
> +			return false;
> +
>  		hwc->config_base = box_ctl + uncore_pci_event_ctl(box, hwc->idx);
>  		hwc->event_base  = box_ctl + uncore_pci_perf_ctr(box, hwc->idx);
>  		return true;
> @@ -567,27 +582,30 @@ static inline int intel_pci_uncore_box_ctl(struct intel_uncore_box *box)
>  
>  void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box)
>  {
> -	struct pci_dev *pdev = box->pci_dev;
>  	int box_ctl = intel_pci_uncore_box_ctl(box);
>  
> +	if (!box_ctl)
> +		return;
> +
>  	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
> -	pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_INT);
> +	pci_write_config_dword(box->pci_dev, box_ctl, GENERIC_PMON_BOX_CTL_INT);
>  }
>  
>  void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box)
>  {
> -	struct pci_dev *pdev = box->pci_dev;
>  	int box_ctl = intel_pci_uncore_box_ctl(box);
>  
> -	pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_FRZ);
> +	if (box_ctl)
> +		pci_write_config_dword(box->pci_dev, box_ctl,
> +				       GENERIC_PMON_BOX_CTL_FRZ);
>  }
>  
>  void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box)
>  {
> -	struct pci_dev *pdev = box->pci_dev;
>  	int box_ctl = intel_pci_uncore_box_ctl(box);
>  
> -	pci_write_config_dword(pdev, box_ctl, 0);
> +	if (box_ctl)
> +		pci_write_config_dword(box->pci_dev, box_ctl, 0);
>  }
>  
>  static void intel_generic_uncore_pci_enable_event(struct intel_uncore_box *box,

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 3/7] perf/x86/intel/uncore: Fix PCI device refcount leak in UPI discovery
  2026-05-27 15:11 ` [PATCH V2 3/7] perf/x86/intel/uncore: Fix PCI device refcount leak in UPI discovery Zide Chen
@ 2026-05-28  6:34   ` Mi, Dapeng
  0 siblings, 0 replies; 20+ messages in thread
From: Mi, Dapeng @ 2026-05-28  6:34 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

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>


On 5/27/2026 11:11 PM, Zide Chen wrote:
> pci_get_domain_bus_and_slot() increments the reference count of the
> returned PCI device and therefore requires a matching pci_dev_put().
>
> In skx_upi_topology_cb() and discover_upi_topology(), the lookup is
> performed inside a loop, but pci_dev_put() is only called once after
> the loop. As a result, references from all previous iterations are
> leaked.
>
> Move pci_dev_put(dev) into the if (dev) block immediately after
> upi_fill_topology() returns.
>
> Opportunistically, fix uninitialized variable in skx_upi_topology_cb().
>
> Fixes: 4cfce57fa42d ("perf/x86/intel/uncore: Enable UPI topology discovery for Skylake Server")
> Fixes: f680b6e6062e ("perf/x86/intel/uncore: Enable UPI topology discovery for Icelake Server")
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
>  arch/x86/events/intel/uncore_snbep.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
> index 215d33e260ed..c9ce206fcbb6 100644
> --- a/arch/x86/events/intel/uncore_snbep.c
> +++ b/arch/x86/events/intel/uncore_snbep.c
> @@ -4261,7 +4261,7 @@ static int upi_fill_topology(struct pci_dev *dev, struct intel_uncore_topology *
>  static int skx_upi_topology_cb(struct intel_uncore_type *type, int segment,
>  				int die, u64 cpu_bus_msr)
>  {
> -	int idx, ret;
> +	int idx, ret = 0;
>  	struct intel_uncore_topology *upi;
>  	unsigned int devfn;
>  	struct pci_dev *dev = NULL;
> @@ -4274,12 +4274,12 @@ static int skx_upi_topology_cb(struct intel_uncore_type *type, int segment,
>  		dev = pci_get_domain_bus_and_slot(segment, bus, devfn);
>  		if (dev) {
>  			ret = upi_fill_topology(dev, upi, idx);
> +			pci_dev_put(dev);
>  			if (ret)
>  				break;
>  		}
>  	}
>  
> -	pci_dev_put(dev);
>  	return ret;
>  }
>  
> @@ -5499,6 +5499,7 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i
>  							  devfn);
>  			if (dev) {
>  				ret = upi_fill_topology(dev, upi, idx);
> +				pci_dev_put(dev);
>  				if (ret)
>  					goto err;
>  			}
> @@ -5506,7 +5507,6 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i
>  	}
>  err:
>  	pci_dev_put(ubox);
> -	pci_dev_put(dev);
>  	return ret;
>  }
>  

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 4/7] perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box()
  2026-05-27 15:11 ` [PATCH V2 4/7] perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box() Zide Chen
@ 2026-05-28  6:35   ` Mi, Dapeng
  2026-05-28 18:07     ` Chen, Zide
  0 siblings, 1 reply; 20+ messages in thread
From: Mi, Dapeng @ 2026-05-28  6:35 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, stable


On 5/27/2026 11:11 PM, Zide Chen wrote:
> On some Raptor Cove CPUs, enabling uncore PMON globally at driver init
> may increase power consumption even when no perf events are in use.
>
> Drop adl_uncore_msr_init_box() and defer programming the global control
> register to enable_box(), so it is only set when a box is actually used.
>
> IMC and IMC freerunning counters use a separate control path and are
> unaffected.
>
> Cc: stable@vger.kernel.org

Need a "Fixes" tag?

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>


> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
>  arch/x86/events/intel/uncore_snb.c | 7 -------
>  1 file changed, 7 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
> index 3dbc6bacbd9d..edddd4f9ab5f 100644
> --- a/arch/x86/events/intel/uncore_snb.c
> +++ b/arch/x86/events/intel/uncore_snb.c
> @@ -563,12 +563,6 @@ void tgl_uncore_cpu_init(void)
>  	skl_uncore_msr_ops.init_box = rkl_uncore_msr_init_box;
>  }
>  
> -static void adl_uncore_msr_init_box(struct intel_uncore_box *box)
> -{
> -	if (box->pmu->pmu_idx == 0)
> -		wrmsrq(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
> -}
> -
>  static void adl_uncore_msr_enable_box(struct intel_uncore_box *box)
>  {
>  	wrmsrq(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
> @@ -587,7 +581,6 @@ static void adl_uncore_msr_exit_box(struct intel_uncore_box *box)
>  }
>  
>  static struct intel_uncore_ops adl_uncore_msr_ops = {
> -	.init_box	= adl_uncore_msr_init_box,
>  	.enable_box	= adl_uncore_msr_enable_box,
>  	.disable_box	= adl_uncore_msr_disable_box,
>  	.exit_box	= adl_uncore_msr_exit_box,

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 5/7] perf/x86/intel/uncore: Move die_to_cpu() to uncore.c
  2026-05-27 15:11 ` [PATCH V2 5/7] perf/x86/intel/uncore: Move die_to_cpu() to uncore.c Zide Chen
@ 2026-05-28  6:36   ` Mi, Dapeng
  2026-05-29 10:54   ` Peter Zijlstra
  1 sibling, 0 replies; 20+ messages in thread
From: Mi, Dapeng @ 2026-05-28  6: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

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>


On 5/27/2026 11:11 PM, Zide Chen wrote:
> Move die_to_cpu() into uncore.c so it can be reused by the MSR
> initialization path, preparing for the introduction of an MSR global
> initialization callback.
>
> Move the cpus_read_{lock,unlock}() out of the API, in order to make
> it possible to be called when the lock is being held.
>
> Add the uncore_ prefix for consistency with other uncore APIs.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
>
> V2:
> - Move cpus_read_{lock,unlock}() out of uncore_die_to_cpu() and rely
>   on callers to manage the lock. (Sashiko)
> - Remove "No functional change intended" from the changelog.
> ---
>  arch/x86/events/intel/uncore.c       | 19 +++++++++++++++++++
>  arch/x86/events/intel/uncore.h       |  1 +
>  arch/x86/events/intel/uncore_snbep.c | 23 +++--------------------
>  3 files changed, 23 insertions(+), 20 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index e9cc1ba921c5..22256ded2d67 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -83,6 +83,25 @@ int uncore_device_to_die(struct pci_dev *dev)
>  	return -1;
>  }
>  
> +/*
> + * Using cpus_read_lock() to ensure cpu is not going down between
> + * looking at cpu_online_mask.
> + *
> + * The lock must be held by the caller.
> + */
> +int uncore_die_to_cpu(int die)
> +{
> +	int res = 0, cpu;
> +
> +	for_each_online_cpu(cpu) {
> +		if (topology_logical_die_id(cpu) == die) {
> +			res = cpu;
> +			break;
> +		}
> +	}
> +	return res;
> +}
> +
>  static void uncore_free_pcibus_map(void)
>  {
>  	struct pci2phy_map *map, *tmp;
> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
> index c35918c01afa..94c68e3417b6 100644
> --- a/arch/x86/events/intel/uncore.h
> +++ b/arch/x86/events/intel/uncore.h
> @@ -235,6 +235,7 @@ struct pci2phy_map *__find_pci2phy_map(int segment);
>  int uncore_pcibus_to_dieid(struct pci_bus *bus);
>  int uncore_die_to_segment(int die);
>  int uncore_device_to_die(struct pci_dev *dev);
> +int uncore_die_to_cpu(int die);
>  
>  ssize_t uncore_event_show(struct device *dev,
>  			  struct device_attribute *attr, char *buf);
> diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
> index c9ce206fcbb6..772b78237424 100644
> --- a/arch/x86/events/intel/uncore_snbep.c
> +++ b/arch/x86/events/intel/uncore_snbep.c
> @@ -3704,25 +3704,6 @@ static int skx_msr_cpu_bus_read(int cpu, u64 *topology)
>  	return 0;
>  }
>  
> -static int die_to_cpu(int die)
> -{
> -	int res = 0, cpu, current_die;
> -	/*
> -	 * Using cpus_read_lock() to ensure cpu is not going down between
> -	 * looking at cpu_online_mask.
> -	 */
> -	cpus_read_lock();
> -	for_each_online_cpu(cpu) {
> -		current_die = topology_logical_die_id(cpu);
> -		if (current_die == die) {
> -			res = cpu;
> -			break;
> -		}
> -	}
> -	cpus_read_unlock();
> -	return res;
> -}
> -
>  enum {
>  	IIO_TOPOLOGY_TYPE,
>  	UPI_TOPOLOGY_TYPE,
> @@ -3794,8 +3775,9 @@ static int skx_pmu_get_topology(struct intel_uncore_type *type,
>  	int die, ret = -EPERM;
>  	u64 cpu_bus_msr;
>  
> +	cpus_read_lock();
>  	for (die = 0; die < uncore_max_dies(); die++) {
> -		ret = skx_msr_cpu_bus_read(die_to_cpu(die), &cpu_bus_msr);
> +		ret = skx_msr_cpu_bus_read(uncore_die_to_cpu(die), &cpu_bus_msr);
>  		if (ret)
>  			break;
>  
> @@ -3807,6 +3789,7 @@ static int skx_pmu_get_topology(struct intel_uncore_type *type,
>  		if (ret)
>  			break;
>  	}
> +	cpus_read_unlock();
>  
>  	return ret;
>  }

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 6/7] perf/x86/intel/uncore: Fix uncore_die_to_cpu() for offline dies
  2026-05-27 15:11 ` [PATCH V2 6/7] perf/x86/intel/uncore: Fix uncore_die_to_cpu() for offline dies Zide Chen
@ 2026-05-28  6:38   ` Mi, Dapeng
  0 siblings, 0 replies; 20+ messages in thread
From: Mi, Dapeng @ 2026-05-28  6:38 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

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>


On 5/27/2026 11:11 PM, Zide Chen wrote:
> If the die is offline when uncore_die_to_cpu() is called, it silently
> returns 0, which is misleading.  Return -1 in this case to indicate
> that all CPUs on the die are offline and the caller can take care of
> it accordingly.
>
> Opportunistically, replace -EPERM with -ENODEV, as -ENODEV is
> the appropriate error when no CPUs are online across all dies.
>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
>  arch/x86/events/intel/uncore.c       | 2 +-
>  arch/x86/events/intel/uncore_snbep.c | 9 +++++++--
>  2 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 22256ded2d67..4b3a1fa5b41b 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -91,7 +91,7 @@ int uncore_device_to_die(struct pci_dev *dev)
>   */
>  int uncore_die_to_cpu(int die)
>  {
> -	int res = 0, cpu;
> +	int res = -1, cpu;
>  
>  	for_each_online_cpu(cpu) {
>  		if (topology_logical_die_id(cpu) == die) {
> diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
> index 772b78237424..334dc384b5b9 100644
> --- a/arch/x86/events/intel/uncore_snbep.c
> +++ b/arch/x86/events/intel/uncore_snbep.c
> @@ -3772,12 +3772,17 @@ static void pmu_free_topology(struct intel_uncore_type *type)
>  static int skx_pmu_get_topology(struct intel_uncore_type *type,
>  				 int (*topology_cb)(struct intel_uncore_type*, int, int, u64))
>  {
> -	int die, ret = -EPERM;
> +	int die, ret = -ENODEV;
>  	u64 cpu_bus_msr;
> +	int cpu;
>  
>  	cpus_read_lock();
>  	for (die = 0; die < uncore_max_dies(); die++) {
> -		ret = skx_msr_cpu_bus_read(uncore_die_to_cpu(die), &cpu_bus_msr);
> +		cpu = uncore_die_to_cpu(die);
> +		if (cpu == -1)
> +			continue;
> +
> +		ret = skx_msr_cpu_bus_read(cpu, &cpu_bus_msr);
>  		if (ret)
>  			break;
>  

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore
  2026-05-27 15:11 ` [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore Zide Chen
@ 2026-05-28  6:46   ` Mi, Dapeng
  2026-05-28 18:14     ` Chen, Zide
  0 siblings, 1 reply; 20+ messages in thread
From: Mi, Dapeng @ 2026-05-28  6:46 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


On 5/27/2026 11:11 PM, Zide Chen wrote:
> On Sierra Forest and Clearwater Forest, the FRZ_ALL bit in the global
> control register defaults to 0 at boot, but UBOX PMON units do not
> work until the global control register is explicitly written with 0
> to trigger hardware initialization properly.
>
> Implement the generic uncore_msr_global_init() callback and add it to
> gnr_uncore_init[], which is shared by GNR, GRR, SRF, and CWF.

Need a "Fixes" tag?

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>


> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> V2:
> - Propagate return value of wrmsrq_on_cpu() to global_init().
> ---
>  arch/x86/events/intel/uncore.c           | 13 ++++++++++++-
>  arch/x86/events/intel/uncore.h           |  2 +-
>  arch/x86/events/intel/uncore_discovery.c |  2 +-
>  3 files changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
> index 4b3a1fa5b41b..7857959c6e82 100644
> --- a/arch/x86/events/intel/uncore.c
> +++ b/arch/x86/events/intel/uncore.c
> @@ -1716,7 +1716,7 @@ static int __init uncore_mmio_init(void)
>  	return ret;
>  }
>  
> -static int uncore_mmio_global_init(u64 ctl)
> +static int uncore_mmio_global_init(int die, u64 ctl)
>  {
>  	void __iomem *io_addr;
>  
> @@ -1731,6 +1731,16 @@ static int uncore_mmio_global_init(u64 ctl)
>  	return 0;
>  }
>  
> +static int uncore_msr_global_init(int die, u64 msr)
> +{
> +	int cpu = uncore_die_to_cpu(die);
> +
> +	if (cpu == -1)
> +		return -ENODEV;
> +
> +	return wrmsrq_on_cpu(cpu, msr, 0);
> +}
> +
>  static const struct uncore_plat_init nhm_uncore_init __initconst = {
>  	.cpu_init = nhm_uncore_cpu_init,
>  };
> @@ -1871,6 +1881,7 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
>  	.domain[0].base_is_pci = true,
>  	.domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
>  	.domain[0].units_ignore = gnr_uncore_units_ignore,
> +	.domain[0].global_init = uncore_msr_global_init,
>  };
>  
>  static const struct uncore_plat_init dmr_uncore_init __initconst = {
> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
> index 94c68e3417b6..c2e5ccb1d72c 100644
> --- a/arch/x86/events/intel/uncore.h
> +++ b/arch/x86/events/intel/uncore.h
> @@ -53,7 +53,7 @@ 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);
> +	int	(*global_init)(int die, 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 af2217b44a81..e36613d934b1 100644
> --- a/arch/x86/events/intel/uncore_discovery.c
> +++ b/arch/x86/events/intel/uncore_discovery.c
> @@ -287,7 +287,7 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
>  	if (!io_addr)
>  		return -ENOMEM;
>  
> -	if (domain->global_init && domain->global_init(global.ctl)) {
> +	if (domain->global_init && domain->global_init(die, global.ctl)) {
>  		ret = -ENODEV;
>  		goto out;
>  	}

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 4/7] perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box()
  2026-05-28  6:35   ` Mi, Dapeng
@ 2026-05-28 18:07     ` Chen, Zide
  0 siblings, 0 replies; 20+ messages in thread
From: Chen, Zide @ 2026-05-28 18:07 UTC (permalink / raw)
  To: Mi, Dapeng, 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, stable



On 5/28/2026 1:35 AM, Mi, Dapeng wrote:
> 
> On 5/27/2026 11:11 PM, Zide Chen wrote:
>> On some Raptor Cove CPUs, enabling uncore PMON globally at driver init
>> may increase power consumption even when no perf events are in use.
>>
>> Drop adl_uncore_msr_init_box() and defer programming the global control
>> register to enable_box(), so it is only set when a box is actually used.
>>
>> IMC and IMC freerunning counters use a separate control path and are
>> unaffected.
>>
>> Cc: stable@vger.kernel.org
> 
> Need a "Fixes" tag?

Not really. This is a workaround for hardware issues rather than a fix
for software bugs.

> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> 
> 
>> Signed-off-by: Zide Chen <zide.chen@intel.com>
>> ---
>>  arch/x86/events/intel/uncore_snb.c | 7 -------
>>  1 file changed, 7 deletions(-)
>>
>> diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
>> index 3dbc6bacbd9d..edddd4f9ab5f 100644
>> --- a/arch/x86/events/intel/uncore_snb.c
>> +++ b/arch/x86/events/intel/uncore_snb.c
>> @@ -563,12 +563,6 @@ void tgl_uncore_cpu_init(void)
>>  	skl_uncore_msr_ops.init_box = rkl_uncore_msr_init_box;
>>  }
>>  
>> -static void adl_uncore_msr_init_box(struct intel_uncore_box *box)
>> -{
>> -	if (box->pmu->pmu_idx == 0)
>> -		wrmsrq(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
>> -}
>> -
>>  static void adl_uncore_msr_enable_box(struct intel_uncore_box *box)
>>  {
>>  	wrmsrq(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN);
>> @@ -587,7 +581,6 @@ static void adl_uncore_msr_exit_box(struct intel_uncore_box *box)
>>  }
>>  
>>  static struct intel_uncore_ops adl_uncore_msr_ops = {
>> -	.init_box	= adl_uncore_msr_init_box,
>>  	.enable_box	= adl_uncore_msr_enable_box,
>>  	.disable_box	= adl_uncore_msr_disable_box,
>>  	.exit_box	= adl_uncore_msr_exit_box,


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore
  2026-05-28  6:46   ` Mi, Dapeng
@ 2026-05-28 18:14     ` Chen, Zide
  2026-05-29  8:47       ` Mi, Dapeng
  0 siblings, 1 reply; 20+ messages in thread
From: Chen, Zide @ 2026-05-28 18:14 UTC (permalink / raw)
  To: Mi, Dapeng, 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



On 5/28/2026 1:46 AM, Mi, Dapeng wrote:
> 
> On 5/27/2026 11:11 PM, Zide Chen wrote:
>> On Sierra Forest and Clearwater Forest, the FRZ_ALL bit in the global
>> control register defaults to 0 at boot, but UBOX PMON units do not
>> work until the global control register is explicitly written with 0
>> to trigger hardware initialization properly.
>>
>> Implement the generic uncore_msr_global_init() callback and add it to
>> gnr_uncore_init[], which is shared by GNR, GRR, SRF, and CWF.
> 
> Need a "Fixes" tag?
No Fixes tag needed. This is a hardware initialization workaround rather
than a fix for a software bug. The register defaults to 0, but the
hardware requires an explicit write to trigger PMON functionality.

> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> 
> 
>> Signed-off-by: Zide Chen <zide.chen@intel.com>
>> ---
>> V2:
>> - Propagate return value of wrmsrq_on_cpu() to global_init().
>> ---
>>  arch/x86/events/intel/uncore.c           | 13 ++++++++++++-
>>  arch/x86/events/intel/uncore.h           |  2 +-
>>  arch/x86/events/intel/uncore_discovery.c |  2 +-
>>  3 files changed, 14 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
>> index 4b3a1fa5b41b..7857959c6e82 100644
>> --- a/arch/x86/events/intel/uncore.c
>> +++ b/arch/x86/events/intel/uncore.c
>> @@ -1716,7 +1716,7 @@ static int __init uncore_mmio_init(void)
>>  	return ret;
>>  }
>>  
>> -static int uncore_mmio_global_init(u64 ctl)
>> +static int uncore_mmio_global_init(int die, u64 ctl)
>>  {
>>  	void __iomem *io_addr;
>>  
>> @@ -1731,6 +1731,16 @@ static int uncore_mmio_global_init(u64 ctl)
>>  	return 0;
>>  }
>>  
>> +static int uncore_msr_global_init(int die, u64 msr)
>> +{
>> +	int cpu = uncore_die_to_cpu(die);
>> +
>> +	if (cpu == -1)
>> +		return -ENODEV;
>> +
>> +	return wrmsrq_on_cpu(cpu, msr, 0);
>> +}
>> +
>>  static const struct uncore_plat_init nhm_uncore_init __initconst = {
>>  	.cpu_init = nhm_uncore_cpu_init,
>>  };
>> @@ -1871,6 +1881,7 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
>>  	.domain[0].base_is_pci = true,
>>  	.domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
>>  	.domain[0].units_ignore = gnr_uncore_units_ignore,
>> +	.domain[0].global_init = uncore_msr_global_init,
>>  };
>>  
>>  static const struct uncore_plat_init dmr_uncore_init __initconst = {
>> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
>> index 94c68e3417b6..c2e5ccb1d72c 100644
>> --- a/arch/x86/events/intel/uncore.h
>> +++ b/arch/x86/events/intel/uncore.h
>> @@ -53,7 +53,7 @@ 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);
>> +	int	(*global_init)(int die, 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 af2217b44a81..e36613d934b1 100644
>> --- a/arch/x86/events/intel/uncore_discovery.c
>> +++ b/arch/x86/events/intel/uncore_discovery.c
>> @@ -287,7 +287,7 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
>>  	if (!io_addr)
>>  		return -ENOMEM;
>>  
>> -	if (domain->global_init && domain->global_init(global.ctl)) {
>> +	if (domain->global_init && domain->global_init(die, global.ctl)) {
>>  		ret = -ENODEV;
>>  		goto out;
>>  	}


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore
  2026-05-28 18:14     ` Chen, Zide
@ 2026-05-29  8:47       ` Mi, Dapeng
  2026-05-29 10:55         ` Peter Zijlstra
  0 siblings, 1 reply; 20+ messages in thread
From: Mi, Dapeng @ 2026-05-29  8:47 UTC (permalink / raw)
  To: Chen, Zide, 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


On 5/29/2026 2:14 AM, Chen, Zide wrote:
>
> On 5/28/2026 1:46 AM, Mi, Dapeng wrote:
>> On 5/27/2026 11:11 PM, Zide Chen wrote:
>>> On Sierra Forest and Clearwater Forest, the FRZ_ALL bit in the global
>>> control register defaults to 0 at boot, but UBOX PMON units do not
>>> work until the global control register is explicitly written with 0
>>> to trigger hardware initialization properly.
>>>
>>> Implement the generic uncore_msr_global_init() callback and add it to
>>> gnr_uncore_init[], which is shared by GNR, GRR, SRF, and CWF.
>> Need a "Fixes" tag?
> No Fixes tag needed. This is a hardware initialization workaround rather
> than a fix for a software bug. The register defaults to 0, but the
> hardware requires an explicit write to trigger PMON functionality.

Zide, per my understanding, some uncore PMUs can't work for SRF and CWF
without this change. Is it right? If so, we need to add a "Fixes" tag to
ensure this patch is merged to the corresponding stable branches. Thanks.


>
>> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
>>
>>
>>> Signed-off-by: Zide Chen <zide.chen@intel.com>
>>> ---
>>> V2:
>>> - Propagate return value of wrmsrq_on_cpu() to global_init().
>>> ---
>>>  arch/x86/events/intel/uncore.c           | 13 ++++++++++++-
>>>  arch/x86/events/intel/uncore.h           |  2 +-
>>>  arch/x86/events/intel/uncore_discovery.c |  2 +-
>>>  3 files changed, 14 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
>>> index 4b3a1fa5b41b..7857959c6e82 100644
>>> --- a/arch/x86/events/intel/uncore.c
>>> +++ b/arch/x86/events/intel/uncore.c
>>> @@ -1716,7 +1716,7 @@ static int __init uncore_mmio_init(void)
>>>  	return ret;
>>>  }
>>>  
>>> -static int uncore_mmio_global_init(u64 ctl)
>>> +static int uncore_mmio_global_init(int die, u64 ctl)
>>>  {
>>>  	void __iomem *io_addr;
>>>  
>>> @@ -1731,6 +1731,16 @@ static int uncore_mmio_global_init(u64 ctl)
>>>  	return 0;
>>>  }
>>>  
>>> +static int uncore_msr_global_init(int die, u64 msr)
>>> +{
>>> +	int cpu = uncore_die_to_cpu(die);
>>> +
>>> +	if (cpu == -1)
>>> +		return -ENODEV;
>>> +
>>> +	return wrmsrq_on_cpu(cpu, msr, 0);
>>> +}
>>> +
>>>  static const struct uncore_plat_init nhm_uncore_init __initconst = {
>>>  	.cpu_init = nhm_uncore_cpu_init,
>>>  };
>>> @@ -1871,6 +1881,7 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
>>>  	.domain[0].base_is_pci = true,
>>>  	.domain[0].discovery_base = UNCORE_DISCOVERY_TABLE_DEVICE,
>>>  	.domain[0].units_ignore = gnr_uncore_units_ignore,
>>> +	.domain[0].global_init = uncore_msr_global_init,
>>>  };
>>>  
>>>  static const struct uncore_plat_init dmr_uncore_init __initconst = {
>>> diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
>>> index 94c68e3417b6..c2e5ccb1d72c 100644
>>> --- a/arch/x86/events/intel/uncore.h
>>> +++ b/arch/x86/events/intel/uncore.h
>>> @@ -53,7 +53,7 @@ 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);
>>> +	int	(*global_init)(int die, 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 af2217b44a81..e36613d934b1 100644
>>> --- a/arch/x86/events/intel/uncore_discovery.c
>>> +++ b/arch/x86/events/intel/uncore_discovery.c
>>> @@ -287,7 +287,7 @@ static int __parse_discovery_table(struct uncore_discovery_domain *domain,
>>>  	if (!io_addr)
>>>  		return -ENOMEM;
>>>  
>>> -	if (domain->global_init && domain->global_init(global.ctl)) {
>>> +	if (domain->global_init && domain->global_init(die, global.ctl)) {
>>>  		ret = -ENODEV;
>>>  		goto out;
>>>  	}
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 5/7] perf/x86/intel/uncore: Move die_to_cpu() to uncore.c
  2026-05-27 15:11 ` [PATCH V2 5/7] perf/x86/intel/uncore: Move die_to_cpu() to uncore.c Zide Chen
  2026-05-28  6:36   ` Mi, Dapeng
@ 2026-05-29 10:54   ` Peter Zijlstra
  1 sibling, 0 replies; 20+ messages in thread
From: Peter Zijlstra @ 2026-05-29 10:54 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

On Wed, May 27, 2026 at 08:11:52AM -0700, Zide Chen wrote:
> Move die_to_cpu() into uncore.c so it can be reused by the MSR
> initialization path, preparing for the introduction of an MSR global
> initialization callback.
> 
> Move the cpus_read_{lock,unlock}() out of the API, in order to make
> it possible to be called when the lock is being held.
> 
> Add the uncore_ prefix for consistency with other uncore APIs.
> 
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> 
> V2:
> - Move cpus_read_{lock,unlock}() out of uncore_die_to_cpu() and rely
>   on callers to manage the lock. (Sashiko)
> - Remove "No functional change intended" from the changelog.
> ---

V2 stuff goes under the '---' line. Otherwise I get to manually delete
it.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore
  2026-05-29  8:47       ` Mi, Dapeng
@ 2026-05-29 10:55         ` Peter Zijlstra
  2026-05-29 15:03           ` Chen, Zide
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Zijlstra @ 2026-05-29 10:55 UTC (permalink / raw)
  To: Mi, Dapeng
  Cc: Chen, Zide, Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim,
	Ian Rogers, Adrian Hunter, Alexander Shishkin, Andi Kleen,
	Eranian Stephane, linux-kernel, linux-perf-users

On Fri, May 29, 2026 at 04:47:39PM +0800, Mi, Dapeng wrote:
> 
> On 5/29/2026 2:14 AM, Chen, Zide wrote:
> >
> > On 5/28/2026 1:46 AM, Mi, Dapeng wrote:
> >> On 5/27/2026 11:11 PM, Zide Chen wrote:
> >>> On Sierra Forest and Clearwater Forest, the FRZ_ALL bit in the global
> >>> control register defaults to 0 at boot, but UBOX PMON units do not
> >>> work until the global control register is explicitly written with 0
> >>> to trigger hardware initialization properly.
> >>>
> >>> Implement the generic uncore_msr_global_init() callback and add it to
> >>> gnr_uncore_init[], which is shared by GNR, GRR, SRF, and CWF.
> >> Need a "Fixes" tag?
> > No Fixes tag needed. This is a hardware initialization workaround rather
> > than a fix for a software bug. The register defaults to 0, but the
> > hardware requires an explicit write to trigger PMON functionality.
> 
> Zide, per my understanding, some uncore PMUs can't work for SRF and CWF
> without this change. Is it right? If so, we need to add a "Fixes" tag to
> ensure this patch is merged to the corresponding stable branches. Thanks.

If you all agree on Fixes tags, then those patches that end up getting
one should be at the front of the series.

I was about to pick this up, but if you guys want to send a new series,
let me know and I'll hold off.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore
  2026-05-29 10:55         ` Peter Zijlstra
@ 2026-05-29 15:03           ` Chen, Zide
  0 siblings, 0 replies; 20+ messages in thread
From: Chen, Zide @ 2026-05-29 15:03 UTC (permalink / raw)
  To: Peter Zijlstra, Mi, Dapeng
  Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Ian Rogers,
	Adrian Hunter, Alexander Shishkin, Andi Kleen, Eranian Stephane,
	linux-kernel, linux-perf-users



On 5/29/2026 5:55 AM, Peter Zijlstra wrote:
> On Fri, May 29, 2026 at 04:47:39PM +0800, Mi, Dapeng wrote:
>>
>> On 5/29/2026 2:14 AM, Chen, Zide wrote:
>>>
>>> On 5/28/2026 1:46 AM, Mi, Dapeng wrote:
>>>> On 5/27/2026 11:11 PM, Zide Chen wrote:
>>>>> On Sierra Forest and Clearwater Forest, the FRZ_ALL bit in the global
>>>>> control register defaults to 0 at boot, but UBOX PMON units do not
>>>>> work until the global control register is explicitly written with 0
>>>>> to trigger hardware initialization properly.
>>>>>
>>>>> Implement the generic uncore_msr_global_init() callback and add it to
>>>>> gnr_uncore_init[], which is shared by GNR, GRR, SRF, and CWF.
>>>> Need a "Fixes" tag?
>>> No Fixes tag needed. This is a hardware initialization workaround rather
>>> than a fix for a software bug. The register defaults to 0, but the
>>> hardware requires an explicit write to trigger PMON functionality.
>>
>> Zide, per my understanding, some uncore PMUs can't work for SRF and CWF
>> without this change. Is it right? If so, we need to add a "Fixes" tag to
>> ensure this patch is merged to the corresponding stable branches. Thanks.
> 
> If you all agree on Fixes tags, then those patches that end up getting
> one should be at the front of the series.
> 
> I was about to pick this up, but if you guys want to send a new series,
> let me know and I'll hold off.

Yes, please hold off and I can send out a new series to add a Fixes tag,
fix the missing '---' in patch 5/7, etc.


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-05-29 15:03 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-27 15:11 [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Zide Chen
2026-05-27 15:11 ` [PATCH V2 2/7] perf/x86/intel/uncore: Guard against invalid box control address Zide Chen
2026-05-28  6:03   ` Mi, Dapeng
2026-05-27 15:11 ` [PATCH V2 3/7] perf/x86/intel/uncore: Fix PCI device refcount leak in UPI discovery Zide Chen
2026-05-28  6:34   ` Mi, Dapeng
2026-05-27 15:11 ` [PATCH V2 4/7] perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box() Zide Chen
2026-05-28  6:35   ` Mi, Dapeng
2026-05-28 18:07     ` Chen, Zide
2026-05-27 15:11 ` [PATCH V2 5/7] perf/x86/intel/uncore: Move die_to_cpu() to uncore.c Zide Chen
2026-05-28  6:36   ` Mi, Dapeng
2026-05-29 10:54   ` Peter Zijlstra
2026-05-27 15:11 ` [PATCH V2 6/7] perf/x86/intel/uncore: Fix uncore_die_to_cpu() for offline dies Zide Chen
2026-05-28  6:38   ` Mi, Dapeng
2026-05-27 15:11 ` [PATCH V2 7/7] perf/x86/intel/uncore: Implement global init callback for GNR uncore Zide Chen
2026-05-28  6:46   ` Mi, Dapeng
2026-05-28 18:14     ` Chen, Zide
2026-05-29  8:47       ` Mi, Dapeng
2026-05-29 10:55         ` Peter Zijlstra
2026-05-29 15:03           ` Chen, Zide
2026-05-28  6:01 ` [PATCH V2 1/7] perf/x86/intel/uncore: Fix discovery unit lookup for multi-die systems Mi, Dapeng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox