From 60b292cab32ba482d8119906fbd4f73c7117c70b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 30 Aug 2004 20:34:59 -0700 Subject: [PATCH] [PATCH] x86_64: emulate NUMA on non-NUMA hardware Apply this handy patch and boot with numa=fake=4 (or how many nodes you want, 8 max right now). There is a minor issue with the hash function, which can make the last node be bigger than the others. Is probably fixable if it should be a problem. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/mm/numa.c | 55 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index c38f0cbc02680..e6746a26b7a8d 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c @@ -162,10 +162,58 @@ void __init numa_init_array(void) set_bit(0, &node_to_cpumask[cpu_to_node(0)]); } +int numa_fake __initdata = 0; + +/* Numa emulation */ +static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn) +{ + int i; + struct node nodes[MAXNODE]; + unsigned long sz = ((end_pfn - start_pfn)< 1) { + unsigned long x = 1; + while ((x << 1) < sz) + x <<= 1; + if (x < sz/2) + printk("Numa emulation unbalanced. Complain to maintainer\n"); + sz = x; + } + + memset(&nodes,0,sizeof(nodes)); + for (i = 0; i < numa_fake; i++) { + nodes[i].start = (start_pfn<> 20); + } + numnodes = numa_fake; + memnode_shift = compute_hash_shift(nodes); + if (memnode_shift < 0) { + memnode_shift = 0; + printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n"); + return -1; + } + for (i = 0; i < numa_fake; i++) + setup_node_bootmem(i, nodes[i].start, nodes[i].end); + numa_init_array(); + return 0; +} + void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) { int i; + if (numa_fake && !numa_emulation(start_pfn, end_pfn)) + return; + #ifdef CONFIG_K8_NUMA if (!numa_off && !k8_scan_nodes(start_pfn<