
From: Olof Johansson <olof@austin.ibm.com>

As discussed on the ppc64 list yesterday and today:

On some ppc64 systems, Open Firmware will give memory device nodes that are
only 16MB in size, instead of the 256MB that our NUMA code currently
expects (see MEMORY_INCREMENT in mmzone.h).

Just changing the defines from 256MB to 16MB makes the table blow up from
32KB to 512KB, so this patch also makes it dynamically allocated based on
actual memory size.  Since all this is done before (well, during) bootmem
init so we need to use lmb_alloc().

Finally, there's no need to use a full int for node ID. Current max is 16
nodes, so a signed char still leaves plenty of room to grow.


---

 25-akpm/arch/ppc64/mm/numa.c       |   21 ++++++++++++++++++---
 25-akpm/include/asm-ppc64/mmzone.h |    6 +++---
 2 files changed, 21 insertions(+), 6 deletions(-)

diff -puN arch/ppc64/mm/numa.c~ppc64-NUMA-fix-for-16MB-LMBs arch/ppc64/mm/numa.c
--- 25/arch/ppc64/mm/numa.c~ppc64-NUMA-fix-for-16MB-LMBs	2004-04-04 16:52:59.838627872 -0700
+++ 25-akpm/arch/ppc64/mm/numa.c	2004-04-04 16:52:59.844626960 -0700
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <asm/lmb.h>
 #include <asm/machdep.h>
+#include <asm/abs_addr.h>
 
 #if 1
 #define dbg(args...) udbg_printf(args)
@@ -31,9 +32,7 @@
 
 int numa_cpu_lookup_table[NR_CPUS] = { [ 0 ... (NR_CPUS - 1)] =
 	ARRAY_INITIALISER};
-int numa_memory_lookup_table[MAX_MEMORY >> MEMORY_INCREMENT_SHIFT] =
-	{ [ 0 ... ((MAX_MEMORY >> MEMORY_INCREMENT_SHIFT) - 1)] =
-	ARRAY_INITIALISER};
+char *numa_memory_lookup_table;
 cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
 int nr_cpus_in_node[MAX_NUMNODES] = { [0 ... (MAX_NUMNODES -1)] = 0};
 
@@ -65,12 +64,20 @@ static int __init parse_numa_properties(
 	int *memory_associativity;
 	int depth;
 	int max_domain = 0;
+	long entries = lmb_end_of_DRAM() >> MEMORY_INCREMENT_SHIFT;
+	long i;
 
 	if (strstr(saved_command_line, "numa=off")) {
 		printk(KERN_WARNING "NUMA disabled by user\n");
 		return -1;
 	}
 
+	numa_memory_lookup_table =
+		(char *)abs_to_virt(lmb_alloc(entries * sizeof(char), 1));
+
+	for (i = 0; i < entries ; i++)
+		numa_memory_lookup_table[i] = ARRAY_INITIALISER;
+
 	cpu = of_find_node_by_type(NULL, "cpu");
 	if (!cpu)
 		goto err;
@@ -232,6 +239,14 @@ static void __init setup_nonnuma(void)
 	printk(KERN_INFO "Memory hole size: %ldMB\n",
 	       (top_of_ram - total_ram) >> 20);
 
+	if (!numa_memory_lookup_table) {
+		long entries = top_of_ram >> MEMORY_INCREMENT_SHIFT;
+		numa_memory_lookup_table =
+			(char *)abs_to_virt(lmb_alloc(entries * sizeof(char), 1));
+		for (i = 0; i < entries ; i++)
+			numa_memory_lookup_table[i] = ARRAY_INITIALISER;
+	}
+
 	for (i = 0; i < NR_CPUS; i++)
 		map_cpu_to_node(i, 0);
 
diff -puN include/asm-ppc64/mmzone.h~ppc64-NUMA-fix-for-16MB-LMBs include/asm-ppc64/mmzone.h
--- 25/include/asm-ppc64/mmzone.h~ppc64-NUMA-fix-for-16MB-LMBs	2004-04-04 16:52:59.839627720 -0700
+++ 25-akpm/include/asm-ppc64/mmzone.h	2004-04-04 16:52:59.844626960 -0700
@@ -19,13 +19,13 @@ extern struct pglist_data node_data[];
  */
 
 extern int numa_cpu_lookup_table[];
-extern int numa_memory_lookup_table[];
+extern char *numa_memory_lookup_table;
 extern cpumask_t numa_cpumask_lookup_table[];
 extern int nr_cpus_in_node[];
 
 #define MAX_MEMORY (1UL << 41)
-/* 256MB regions */
-#define MEMORY_INCREMENT_SHIFT 28
+/* 16MB regions */
+#define MEMORY_INCREMENT_SHIFT 24
 #define MEMORY_INCREMENT (1UL << MEMORY_INCREMENT_SHIFT)
 
 /* NUMA debugging, will not work on a DLPAR machine */

_
