Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf/x86/intel/uncore: Fix die ID init and look up bugs

In snbep_pci2phy_map_init(), in the nr_node_ids > 8 path,
uncore_device_to_die() may return -1 when all CPUs associated
with the UBOX device are offline.

Remove the WARN_ON_ONCE(die_id == -1) check for two reasons:

- The current code breaks out of the loop. This is incorrect because
pci_get_device() does not guarantee iteration in domain or bus order,
so additional UBOX devices may be skipped during the scan.

- Returning -EINVAL is incorrect, since marking offline buses with
die_id == -1 is expected and should not be treated as an error.

Separately, when NUMA is disabled on a NUMA-capable platform,
pcibus_to_node() returns NUMA_NO_NODE, causing uncore_device_to_die()
to return -1 for all PCI devices. As a result,
spr_update_device_location(), used on Intel SPR and EMR, ignores the
corresponding PMON units and does not add them to the RB tree.

Fix this by using uncore_pcibus_to_dieid(), which retrieves topology
from the UBOX GIDNIDMAP register and works regardless of whether NUMA
is enabled in Linux. This requires snbep_pci2phy_map_init() to be
added in spr_uncore_pci_init().

Keep uncore_device_to_die() only for the nr_node_ids > 8 case, where
NUMA is expected to be enabled.

Fixes: 9a7832ce3d92 ("perf/x86/intel/uncore: With > 8 nodes, get pci bus die id from NUMA info")
Fixes: 65248a9a9ee1 ("perf/x86/uncore: Add a quirk for UPI on SPR")
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Tested-by: Steve Wahl <steve.wahl@hpe.com>
Link: https://patch.msgid.link/20260313174050.171704-4-zide.chen@intel.com

authored by

Zide Chen and committed by
Peter Zijlstra
a16d1ec4 7b568e9e

+7 -7
+1
arch/x86/events/intel/uncore.c
··· 67 67 return bus ? pci_domain_nr(bus) : -EINVAL; 68 68 } 69 69 70 + /* Note: This API can only be used when NUMA information is available. */ 70 71 int uncore_device_to_die(struct pci_dev *dev) 71 72 { 72 73 int node = pcibus_to_node(dev->bus);
+6 -7
arch/x86/events/intel/uncore_snbep.c
··· 1459 1459 } 1460 1460 1461 1461 map->pbus_to_dieid[bus] = die_id = uncore_device_to_die(ubox_dev); 1462 - 1463 1462 raw_spin_unlock(&pci2phy_map_lock); 1464 - 1465 - if (WARN_ON_ONCE(die_id == -1)) { 1466 - err = -EINVAL; 1467 - break; 1468 - } 1469 1463 } 1470 1464 } 1471 1465 ··· 6414 6420 6415 6421 while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, dev)) != NULL) { 6416 6422 6417 - die = uncore_device_to_die(dev); 6423 + die = uncore_pcibus_to_dieid(dev->bus); 6418 6424 if (die < 0) 6419 6425 continue; 6420 6426 ··· 6438 6444 6439 6445 int spr_uncore_pci_init(void) 6440 6446 { 6447 + int ret = snbep_pci2phy_map_init(0x3250, SKX_CPUNODEID, SKX_GIDNIDMAP, true); 6448 + 6449 + if (ret) 6450 + return ret; 6451 + 6441 6452 /* 6442 6453 * The discovery table of UPI on some SPR variant is broken, 6443 6454 * which impacts the detection of both UPI and M3UPI uncore PMON.