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.

x86/platform/uv: Use alternate source for socket to node data

The UV code attempts to build a set of tables to allow it to do
bidirectional socket<=>node lookups.

But when nr_cpus is set to a smaller number than actually present, the
cpu_to_node() mapping information for unused CPUs is not available to
build_socket_tables(). This results in skipping some nodes or sockets
when creating the tables and leaving some -1's for later code to trip.
over, causing oopses.

The problem is that the socket<=>node lookups are created by doing a
loop over all CPUs, then looking up the CPU's APICID and socket. But
if a CPU is not present, there is no way to start this lookup.

Instead of looping over all CPUs, take CPUs out of the equation
entirely. Loop over all APICIDs which are mapped to a valid NUMA node.
Then just extract the socket-id from the APICID.

This avoid tripping over disabled CPUs.

Fixes: 8a50c5851927 ("x86/platform/uv: UV support for sub-NUMA clustering")
Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/20230807141730.1117278-1-steve.wahl%40hpe.com

authored by

Steve Wahl and committed by
Dave Hansen
5290e88b 0bb80ecc

+5 -6
+5 -6
arch/x86/kernel/apic/x2apic_uv_x.c
··· 1533 1533 { 1534 1534 struct uv_gam_range_entry *gre = uv_gre_table; 1535 1535 int nums, numn, nump; 1536 - int cpu, i, lnid; 1536 + int i, lnid, apicid; 1537 1537 int minsock = _min_socket; 1538 1538 int maxsock = _max_socket; 1539 1539 int minpnode = _min_pnode; ··· 1584 1584 1585 1585 /* Set socket -> node values: */ 1586 1586 lnid = NUMA_NO_NODE; 1587 - for_each_possible_cpu(cpu) { 1588 - int nid = cpu_to_node(cpu); 1589 - int apicid, sockid; 1587 + for (apicid = 0; apicid < ARRAY_SIZE(__apicid_to_node); apicid++) { 1588 + int nid = __apicid_to_node[apicid]; 1589 + int sockid; 1590 1590 1591 - if (lnid == nid) 1591 + if ((nid == NUMA_NO_NODE) || (lnid == nid)) 1592 1592 continue; 1593 1593 lnid = nid; 1594 1594 1595 - apicid = per_cpu(x86_cpu_to_apicid, cpu); 1596 1595 sockid = apicid >> uv_cpuid.socketid_shift; 1597 1596 1598 1597 if (_socket_to_node[sockid - minsock] == SOCK_EMPTY)