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

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
...@@ -1370,40 +1370,77 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool ...@@ -1370,40 +1370,77 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool
if (!ubox_dev) if (!ubox_dev)
break; break;
bus = ubox_dev->bus->number; bus = ubox_dev->bus->number;
/* get the Node ID of the local register */ /*
err = pci_read_config_dword(ubox_dev, nodeid_loc, &config); * The nodeid and idmap registers only contain enough
if (err) * information to handle 8 nodes. On systems with more
break; * than 8 nodes, we need to rely on NUMA information,
nodeid = config & NODE_ID_MASK; * filled in from BIOS supplied information, to determine
/* get the Node ID mapping */ * the topology.
err = pci_read_config_dword(ubox_dev, idmap_loc, &config); */
if (err) if (nr_node_ids <= 8) {
break; /* get the Node ID of the local register */
err = pci_read_config_dword(ubox_dev, nodeid_loc, &config);
if (err)
break;
nodeid = config & NODE_ID_MASK;
/* get the Node ID mapping */
err = pci_read_config_dword(ubox_dev, idmap_loc, &config);
if (err)
break;
segment = pci_domain_nr(ubox_dev->bus); segment = pci_domain_nr(ubox_dev->bus);
raw_spin_lock(&pci2phy_map_lock); raw_spin_lock(&pci2phy_map_lock);
map = __find_pci2phy_map(segment); map = __find_pci2phy_map(segment);
if (!map) { if (!map) {
raw_spin_unlock(&pci2phy_map_lock);
err = -ENOMEM;
break;
}
/*
* every three bits in the Node ID mapping register maps
* to a particular node.
*/
for (i = 0; i < 8; i++) {
if (nodeid == ((config >> (3 * i)) & 0x7)) {
if (topology_max_die_per_package() > 1)
die_id = i;
else
die_id = topology_phys_to_logical_pkg(i);
map->pbus_to_dieid[bus] = die_id;
break;
}
}
raw_spin_unlock(&pci2phy_map_lock); raw_spin_unlock(&pci2phy_map_lock);
err = -ENOMEM; } else {
break; 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;
* every three bits in the Node ID mapping register maps for_each_cpu(cpu, cpumask_of_pcibus(ubox_dev->bus)) {
* to a particular node. struct cpuinfo_x86 *c = &cpu_data(cpu);
*/
for (i = 0; i < 8; i++) { if (c->initialized && cpu_to_node(cpu) == node) {
if (nodeid == ((config >> (3 * i)) & 0x7)) { map->pbus_to_dieid[bus] = die_id = c->logical_die_id;
if (topology_max_die_per_package() > 1) break;
die_id = i; }
else }
die_id = topology_phys_to_logical_pkg(i); raw_spin_unlock(&pci2phy_map_lock);
map->pbus_to_dieid[bus] = die_id;
if (WARN_ON_ONCE(die_id == -1)) {
err = -EINVAL;
break; break;
} }
} }
raw_spin_unlock(&pci2phy_map_lock);
} }
if (!err) { if (!err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment