aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/numa_64.c
diff options
context:
space:
mode:
authorSuresh Siddha <suresh.b.siddha@intel.com>2008-03-25 13:14:35 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-19 13:19:55 -0400
commit6ec6e0d9f2fd7cb6ca6bc3bfab5ae7b5cdd8c36f (patch)
treebf05991fd8ecf8acd76fc48f5613ddc7bcb6926f /arch/x86/mm/numa_64.c
parent8705a49c35be088a50b8d5fc5e1aa24d6711fd5b (diff)
srat, x86: add support for nodes spanning other nodes
For example, If the physical address layout on a two node system with 8 GB memory is something like: node 0: 0-2GB, 4-6GB node 1: 2-4GB, 6-8GB Current kernels fail to boot/detect this NUMA topology. ACPI SRAT tables can expose such a topology which needs to be supported. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/mm/numa_64.c')
-rw-r--r--arch/x86/mm/numa_64.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 2ea56f48f29b..cb3170186355 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -60,7 +60,7 @@ unsigned long __initdata nodemap_size;
60 * -1 if node overlap or lost ram (shift too big) 60 * -1 if node overlap or lost ram (shift too big)
61 */ 61 */
62static int __init populate_memnodemap(const struct bootnode *nodes, 62static int __init populate_memnodemap(const struct bootnode *nodes,
63 int numnodes, int shift) 63 int numnodes, int shift, int *nodeids)
64{ 64{
65 unsigned long addr, end; 65 unsigned long addr, end;
66 int i, res = -1; 66 int i, res = -1;
@@ -76,7 +76,12 @@ static int __init populate_memnodemap(const struct bootnode *nodes,
76 do { 76 do {
77 if (memnodemap[addr >> shift] != NUMA_NO_NODE) 77 if (memnodemap[addr >> shift] != NUMA_NO_NODE)
78 return -1; 78 return -1;
79 memnodemap[addr >> shift] = i; 79
80 if (!nodeids)
81 memnodemap[addr >> shift] = i;
82 else
83 memnodemap[addr >> shift] = nodeids[i];
84
80 addr += (1UL << shift); 85 addr += (1UL << shift);
81 } while (addr < end); 86 } while (addr < end);
82 res = 1; 87 res = 1;
@@ -139,7 +144,8 @@ static int __init extract_lsb_from_nodes(const struct bootnode *nodes,
139 return i; 144 return i;
140} 145}
141 146
142int __init compute_hash_shift(struct bootnode *nodes, int numnodes) 147int __init compute_hash_shift(struct bootnode *nodes, int numnodes,
148 int *nodeids)
143{ 149{
144 int shift; 150 int shift;
145 151
@@ -149,7 +155,7 @@ int __init compute_hash_shift(struct bootnode *nodes, int numnodes)
149 printk(KERN_DEBUG "NUMA: Using %d for the hash shift.\n", 155 printk(KERN_DEBUG "NUMA: Using %d for the hash shift.\n",
150 shift); 156 shift);
151 157
152 if (populate_memnodemap(nodes, numnodes, shift) != 1) { 158 if (populate_memnodemap(nodes, numnodes, shift, nodeids) != 1) {
153 printk(KERN_INFO "Your memory is not aligned you need to " 159 printk(KERN_INFO "Your memory is not aligned you need to "
154 "rebuild your kernel with a bigger NODEMAPSIZE " 160 "rebuild your kernel with a bigger NODEMAPSIZE "
155 "shift=%d\n", shift); 161 "shift=%d\n", shift);
@@ -462,7 +468,7 @@ done:
462 } 468 }
463 } 469 }
464out: 470out:
465 memnode_shift = compute_hash_shift(nodes, num_nodes); 471 memnode_shift = compute_hash_shift(nodes, num_nodes, NULL);
466 if (memnode_shift < 0) { 472 if (memnode_shift < 0) {
467 memnode_shift = 0; 473 memnode_shift = 0;
468 printk(KERN_ERR "No NUMA hash function found. NUMA emulation " 474 printk(KERN_ERR "No NUMA hash function found. NUMA emulation "