diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2008-03-25 13:14:35 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-19 13:19:55 -0400 |
commit | 6ec6e0d9f2fd7cb6ca6bc3bfab5ae7b5cdd8c36f (patch) | |
tree | bf05991fd8ecf8acd76fc48f5613ddc7bcb6926f /arch/x86/mm/numa_64.c | |
parent | 8705a49c35be088a50b8d5fc5e1aa24d6711fd5b (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.c | 16 |
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 | */ |
62 | static int __init populate_memnodemap(const struct bootnode *nodes, | 62 | static 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 | ||
142 | int __init compute_hash_shift(struct bootnode *nodes, int numnodes) | 147 | int __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 | } |
464 | out: | 470 | out: |
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 " |