Commit 9a7832ce authored by Steve Wahl's avatar Steve Wahl Committed by Peter Zijlstra
Browse files

perf/x86/intel/uncore: With > 8 nodes, get pci bus die id from NUMA info



The registers used to determine which die a pci bus belongs to don't
contain enough information to uniquely specify more than 8 dies, so
when more than 8 dies are present, use NUMA information instead.

Continue to use the previous method for 8 or fewer because it
works there, and covers cases of NUMA being disabled.

Signed-off-by: default avatarSteve Wahl <steve.wahl@hpe.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarKan Liang <kan.liang@linux.intel.com>
Link: https://lkml.kernel.org/r/20210108153549.108989-3-steve.wahl@hpe.com
parent ba9506be
Loading
Loading
Loading
Loading
+65 −28
Original line number Diff line number Diff line
@@ -1370,6 +1370,14 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool
		if (!ubox_dev)
			break;
		bus = ubox_dev->bus->number;
		/*
		 * The nodeid and idmap registers only contain enough
		 * information to handle 8 nodes.  On systems with more
		 * than 8 nodes, we need to rely on NUMA information,
		 * filled in from BIOS supplied information, to determine
		 * the topology.
		 */
		if (nr_node_ids <= 8) {
			/* get the Node ID of the local register */
			err = pci_read_config_dword(ubox_dev, nodeid_loc, &config);
			if (err)
@@ -1404,6 +1412,35 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool
				}
			}
			raw_spin_unlock(&pci2phy_map_lock);
		} else {
			int node = pcibus_to_node(ubox_dev->bus);
			int cpu;

			segment = pci_domain_nr(ubox_dev->bus);
			raw_spin_lock(&pci2phy_map_lock);
			map = __find_pci2phy_map(segment);
			if (!map) {
				raw_spin_unlock(&pci2phy_map_lock);
				err = -ENOMEM;
				break;
			}

			die_id = -1;
			for_each_cpu(cpu, cpumask_of_pcibus(ubox_dev->bus)) {
				struct cpuinfo_x86 *c = &cpu_data(cpu);

				if (c->initialized && cpu_to_node(cpu) == node) {
					map->pbus_to_dieid[bus] = die_id = c->logical_die_id;
					break;
				}
			}
			raw_spin_unlock(&pci2phy_map_lock);

			if (WARN_ON_ONCE(die_id == -1)) {
				err = -EINVAL;
				break;
			}
		}
	}

	if (!err) {