Skip to content

Commit f68376f

Browse files
Dimitri SivanichIngo Molnar
authored andcommitted
x86/platform/UV: Fix incorrect nodes and pnodes for cpuless and memoryless nodes
This patch fixes the problem of incorrect nodes and pnodes being returned when referring to nodes that either have no cpus (AKA "headless") or no memory. Tested-by: John Estabrook <[email protected]> Tested-by: Gary Kroening <[email protected]> Tested-by: Nathan Zimmer <[email protected]> Signed-off-by: Dimitri Sivanich <[email protected]> Signed-off-by: Mike Travis <[email protected]> Cc: Andrew Banman <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Len Brown <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Russ Anderson <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 40bfb8e commit f68376f

File tree

1 file changed

+28
-30
lines changed

1 file changed

+28
-30
lines changed

arch/x86/kernel/apic/x2apic_uv_x.c

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,8 +1232,7 @@ static void __init decode_uv_systab(void)
12321232
*/
12331233
static __init void boot_init_possible_blades(struct uv_hub_info_s *hub_info)
12341234
{
1235-
size_t bytes;
1236-
int blade, i, j, uv_pb = 0, num_nodes = num_possible_nodes();
1235+
int i, uv_pb = 0;
12371236

12381237
pr_info("UV: NODE_PRESENT_DEPTH = %d\n", UVH_NODE_PRESENT_TABLE_DEPTH);
12391238
for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) {
@@ -1247,28 +1246,6 @@ static __init void boot_init_possible_blades(struct uv_hub_info_s *hub_info)
12471246
}
12481247
if (uv_possible_blades != uv_pb)
12491248
uv_possible_blades = uv_pb;
1250-
1251-
bytes = num_nodes * sizeof(_node_to_pnode[0]);
1252-
_node_to_pnode = kmalloc(bytes, GFP_KERNEL);
1253-
BUG_ON(!_node_to_pnode);
1254-
1255-
for (blade = 0, i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) {
1256-
unsigned short pnode;
1257-
unsigned long present =
1258-
uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8);
1259-
1260-
for (j = 0; j < 64; j++) {
1261-
if (!test_bit(j, &present))
1262-
continue;
1263-
pnode = (i * 64 + j) & hub_info->pnode_mask;
1264-
_node_to_pnode[blade++] = pnode;
1265-
}
1266-
if (blade > num_nodes) {
1267-
pr_err("UV: blade count(%d) exceeds node count(%d)!\n",
1268-
blade, num_nodes);
1269-
BUG();
1270-
}
1271-
}
12721249
}
12731250

12741251
static void __init build_socket_tables(void)
@@ -1449,7 +1426,6 @@ void __init uv_system_init(void)
14491426
bytes = sizeof(struct uv_hub_info_s);
14501427
for_each_node(nodeid) {
14511428
struct uv_hub_info_s *new_hub;
1452-
unsigned short pnode;
14531429

14541430
if (__uv_hub_info_list[nodeid]) {
14551431
pr_err("UV: Node %d UV HUB already initialized!?\n",
@@ -1467,10 +1443,11 @@ void __init uv_system_init(void)
14671443
BUG_ON(!new_hub);
14681444
*new_hub = hub_info;
14691445

1470-
pnode = _node_to_pnode[nodeid];
1471-
min_pnode = min(pnode, min_pnode);
1472-
max_pnode = max(pnode, max_pnode);
1473-
new_hub->pnode = pnode;
1446+
/* Use information from GAM table if available */
1447+
if (_node_to_pnode)
1448+
new_hub->pnode = _node_to_pnode[nodeid];
1449+
else /* Fill in during cpu loop */
1450+
new_hub->pnode = 0xffff;
14741451
new_hub->numa_blade_id = uv_node_to_blade_id(nodeid);
14751452
new_hub->memory_nid = -1;
14761453
new_hub->nr_possible_cpus = 0;
@@ -1480,18 +1457,39 @@ void __init uv_system_init(void)
14801457
/* Initialize per cpu info */
14811458
for_each_possible_cpu(cpu) {
14821459
int apicid = per_cpu(x86_cpu_to_apicid, cpu);
1460+
int numa_node_id;
1461+
unsigned short pnode;
14831462

14841463
nodeid = cpu_to_node(cpu);
1464+
numa_node_id = numa_cpu_node(cpu);
1465+
pnode = uv_apicid_to_pnode(apicid);
1466+
14851467
uv_cpu_info_per(cpu)->p_uv_hub_info = uv_hub_info_list(nodeid);
14861468
uv_cpu_info_per(cpu)->blade_cpu_id =
14871469
uv_cpu_hub_info(cpu)->nr_possible_cpus++;
14881470
if (uv_cpu_hub_info(cpu)->memory_nid == -1)
14891471
uv_cpu_hub_info(cpu)->memory_nid = cpu_to_node(cpu);
1472+
if (nodeid != numa_node_id && /* init memoryless node */
1473+
uv_hub_info_list(numa_node_id)->pnode == 0xffff)
1474+
uv_hub_info_list(numa_node_id)->pnode = pnode;
1475+
else if (uv_cpu_hub_info(cpu)->pnode == 0xffff)
1476+
uv_cpu_hub_info(cpu)->pnode = pnode;
14901477
uv_cpu_scir_info(cpu)->offset = uv_scir_offset(apicid);
14911478
}
14921479

1493-
/* Display per node info */
14941480
for_each_node(nodeid) {
1481+
unsigned short pnode = uv_hub_info_list(nodeid)->pnode;
1482+
1483+
/* Add pnode info for pre-GAM list nodes without cpus */
1484+
if (pnode == 0xffff) {
1485+
unsigned long paddr;
1486+
1487+
paddr = node_start_pfn(nodeid) << PAGE_SHIFT;
1488+
pnode = uv_gpa_to_pnode(uv_soc_phys_ram_to_gpa(paddr));
1489+
uv_hub_info_list(nodeid)->pnode = pnode;
1490+
}
1491+
min_pnode = min(pnode, min_pnode);
1492+
max_pnode = max(pnode, max_pnode);
14951493
pr_info("UV: UVHUB node:%2d pn:%02x nrcpus:%d\n",
14961494
nodeid,
14971495
uv_hub_info_list(nodeid)->pnode,

0 commit comments

Comments
 (0)