From: Anton Blanchard It was possible to hotplug add a new cpu that was larger than numnode. This meant we had a cpu with a node id that didnt have any NODE_DATA() backing it. The following patch catches this in numa_setup_cpu and forces the node to 0. We also make a pass through all cpus at boot to look for the maximum node id - this catches the case at boot. As for hotplug, since the node doesnt have any memory backing it (otherwise the node would have been onlined) then we can assume the machine isnt configured for performance and just force the cpu into node 0. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc64/mm/numa.c | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletion(-) diff -puN arch/ppc64/mm/numa.c~ppc64-fix-for-cpu-hotplug-numa arch/ppc64/mm/numa.c --- 25/arch/ppc64/mm/numa.c~ppc64-fix-for-cpu-hotplug-numa 2004-11-09 21:28:40.047228264 -0800 +++ 25-akpm/arch/ppc64/mm/numa.c 2004-11-09 21:28:40.051227656 -0800 @@ -216,7 +216,7 @@ static int numa_setup_cpu(unsigned long numa_domain = of_node_numa_domain(cpu); - if (numa_domain >= MAX_NUMNODES) { + if (numa_domain >= numnodes) { /* * POWER4 LPAR uses 0xffff as invalid node, * dont warn in this case. @@ -265,6 +265,7 @@ static int cpu_numa_callback(struct noti static int __init parse_numa_properties(void) { + struct device_node *cpu = NULL; struct device_node *memory = NULL; int max_domain = 0; long entries = lmb_end_of_DRAM() >> MEMORY_INCREMENT_SHIFT; @@ -290,6 +291,28 @@ static int __init parse_numa_properties( max_domain = numa_setup_cpu(boot_cpuid); + /* + * Even though we connect cpus to numa domains later in SMP init, + * we need to know the maximum node id now. This is because each + * node id must have NODE_DATA etc backing it. + * As a result of hotplug we could still have cpus appear later on + * with larger node ids. In that case we force the cpu into node 0. + */ + for_each_cpu(i) { + int numa_domain; + + cpu = find_cpu_node(i); + + if (cpu) { + numa_domain = of_node_numa_domain(cpu); + of_node_put(cpu); + + if (numa_domain < MAX_NUMNODES && + max_domain < numa_domain) + max_domain = numa_domain; + } + } + memory = NULL; while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { unsigned long start; _