From 9aebbdb637a73a6092e1456ebb4a2df32cc1f611 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 20 Jul 2010 13:24:30 -0700 Subject: x86, numa: fix boot without RAM on node0 again Commit e534c7c5f8d6 ("numa: x86_64: use generic percpu var numa_node_id() implementation") broke numa systems that don't have ram on node0 when MEMORY_HOTPLUG is enabled, because cpu_up() will call cpu_to_node() before per_cpu(numa_node) is setup for APs. When Node0 doesn't have RAM, on x86, cpus already round it to nearest node with RAM in x86_cpu_to_node_map. and per_cpu(numa_node) is not set up until in c_init for APs. When later cpu_up() calling cpu_to_node() will get 0 again, and make it online even there is no RAM on node0. so later all APs can not booted up, and later will have panic. [ 1.611101] On node 0 totalpages: 0 ......... [ 2.608558] On node 0 totalpages: 0 [ 2.612065] Brought up 1 CPUs [ 2.615199] Total of 1 processors activated (3990.31 BogoMIPS). ... 93.225341] calling loop_init+0x0/0x1a4 @ 1 [ 93.229314] PERCPU: allocation failed, size=80 align=8, failed to populate [ 93.246539] Pid: 1, comm: swapper Tainted: G W 2.6.35-rc4-tip-yh-04371-gd64e6c4-dirty #354 [ 93.264621] Call Trace: [ 93.266533] [] pcpu_alloc+0x83a/0x8e7 [ 93.270710] [] __alloc_percpu+0x10/0x12 [ 93.285849] [] alloc_disk_node+0x94/0x16d [ 93.291811] [] alloc_disk+0x11/0x13 [ 93.306157] [] loop_alloc+0xa7/0x180 [ 93.310538] [] loop_init+0x9b/0x1a4 [ 93.324909] [] ? loop_init+0x0/0x1a4 [ 93.329650] [] do_one_initcall+0x57/0x136 [ 93.345197] [] kernel_init+0x184/0x20e [ 93.348146] [] kernel_thread_helper+0x4/0x10 [ 93.365194] [] ? restore_args+0x0/0x30 [ 93.369305] [] ? kernel_init+0x0/0x20e [ 93.386011] [] ? kernel_thread_helper+0x0/0x10 [ 93.392047] loop: out of memory ... Try to assign per_cpu(numa_node) early [akpm@linux-foundation.org: tidy up code comment] Signed-off-by: Yinghai Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Tejun Heo Cc: Denys Vlasenko Acked-by: Lee Schermerhorn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/kernel/setup_percpu.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index de3b63ae3da2..690c2c09faf3 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -238,6 +238,15 @@ void __init setup_per_cpu_areas(void) #ifdef CONFIG_NUMA per_cpu(x86_cpu_to_node_map, cpu) = early_per_cpu_map(x86_cpu_to_node_map, cpu); + /* + * Ensure taht the boot cpu numa_node is correct when the boot + * cpu is on a node that doesn't have memory installed. + * Also cpu_up() will call cpu_to_node() for APs when + * MEMORY_HOTPLUG is defined, before per_cpu(numa_node) is set + * up later with c_init aka intel_init/amd_init. + * So set them all (boot cpu and all APs). + */ + set_cpu_numa_node(cpu, early_cpu_to_node(cpu)); #endif #endif /* @@ -257,14 +266,6 @@ void __init setup_per_cpu_areas(void) early_per_cpu_ptr(x86_cpu_to_node_map) = NULL; #endif -#if defined(CONFIG_X86_64) && defined(CONFIG_NUMA) - /* - * make sure boot cpu numa_node is right, when boot cpu is on the - * node that doesn't have mem installed - */ - set_cpu_numa_node(boot_cpu_id, early_cpu_to_node(boot_cpu_id)); -#endif - /* Setup node to cpumask map */ setup_node_to_cpumask_map(); -- cgit v1.2.3