diff options
author | Tejun Heo <tj@kernel.org> | 2011-02-16 06:13:07 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-02-16 06:13:07 -0500 |
commit | 206e42087a037fa3adca8908fd318a0cb64d4dee (patch) | |
tree | 044cc262b03c62064a65d13b119b6f73da5c22f4 /arch/x86 | |
parent | 45fe6c78c4ccc384044d1b4877eebe7acf359e76 (diff) |
x86-64, NUMA: Use common numa_nodes[]
ACPI and amd are using separate nodes[] array. Add numa_nodes[] and
use them in all NUMA init methods. cutoff_node() cleanup is moved
from srat_64.c to numa_64.c and applied in initmem_init() regardless
of init methods.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Shaohui Zheng <shaohui.zheng@intel.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/numa_64.h | 1 | ||||
-rw-r--r-- | arch/x86/mm/amdtopology_64.c | 19 | ||||
-rw-r--r-- | arch/x86/mm/numa_64.c | 24 | ||||
-rw-r--r-- | arch/x86/mm/srat_64.c | 43 |
4 files changed, 45 insertions, 42 deletions
diff --git a/arch/x86/include/asm/numa_64.h b/arch/x86/include/asm/numa_64.h index de459365d52..d3a45147d09 100644 --- a/arch/x86/include/asm/numa_64.h +++ b/arch/x86/include/asm/numa_64.h | |||
@@ -29,6 +29,7 @@ extern void setup_node_bootmem(int nodeid, unsigned long start, | |||
29 | 29 | ||
30 | extern nodemask_t cpu_nodes_parsed __initdata; | 30 | extern nodemask_t cpu_nodes_parsed __initdata; |
31 | extern nodemask_t mem_nodes_parsed __initdata; | 31 | extern nodemask_t mem_nodes_parsed __initdata; |
32 | extern struct bootnode numa_nodes[MAX_NUMNODES] __initdata; | ||
32 | 33 | ||
33 | extern int __cpuinit numa_cpu_node(int cpu); | 34 | extern int __cpuinit numa_cpu_node(int cpu); |
34 | 35 | ||
diff --git a/arch/x86/mm/amdtopology_64.c b/arch/x86/mm/amdtopology_64.c index b6029a6b129..f049fa67ed7 100644 --- a/arch/x86/mm/amdtopology_64.c +++ b/arch/x86/mm/amdtopology_64.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <asm/apic.h> | 26 | #include <asm/apic.h> |
27 | #include <asm/amd_nb.h> | 27 | #include <asm/amd_nb.h> |
28 | 28 | ||
29 | static struct bootnode __initdata nodes[8]; | ||
30 | static unsigned char __initdata nodeids[8]; | 29 | static unsigned char __initdata nodeids[8]; |
31 | 30 | ||
32 | static __init int find_northbridge(void) | 31 | static __init int find_northbridge(void) |
@@ -166,8 +165,8 @@ int __init amd_numa_init(void) | |||
166 | pr_info("Node %d MemBase %016lx Limit %016lx\n", | 165 | pr_info("Node %d MemBase %016lx Limit %016lx\n", |
167 | nodeid, base, limit); | 166 | nodeid, base, limit); |
168 | 167 | ||
169 | nodes[nodeid].start = base; | 168 | numa_nodes[nodeid].start = base; |
170 | nodes[nodeid].end = limit; | 169 | numa_nodes[nodeid].end = limit; |
171 | 170 | ||
172 | prevbase = base; | 171 | prevbase = base; |
173 | 172 | ||
@@ -210,8 +209,8 @@ void __init amd_get_nodes(struct bootnode *physnodes) | |||
210 | int i; | 209 | int i; |
211 | 210 | ||
212 | for_each_node_mask(i, mem_nodes_parsed) { | 211 | for_each_node_mask(i, mem_nodes_parsed) { |
213 | physnodes[i].start = nodes[i].start; | 212 | physnodes[i].start = numa_nodes[i].start; |
214 | physnodes[i].end = nodes[i].end; | 213 | physnodes[i].end = numa_nodes[i].end; |
215 | } | 214 | } |
216 | } | 215 | } |
217 | 216 | ||
@@ -221,7 +220,7 @@ static int __init find_node_by_addr(unsigned long addr) | |||
221 | int i; | 220 | int i; |
222 | 221 | ||
223 | for (i = 0; i < 8; i++) | 222 | for (i = 0; i < 8; i++) |
224 | if (addr >= nodes[i].start && addr < nodes[i].end) { | 223 | if (addr >= numa_nodes[i].start && addr < numa_nodes[i].end) { |
225 | ret = i; | 224 | ret = i; |
226 | break; | 225 | break; |
227 | } | 226 | } |
@@ -274,7 +273,7 @@ int __init amd_scan_nodes(void) | |||
274 | { | 273 | { |
275 | int i; | 274 | int i; |
276 | 275 | ||
277 | memnode_shift = compute_hash_shift(nodes, 8, NULL); | 276 | memnode_shift = compute_hash_shift(numa_nodes, 8, NULL); |
278 | if (memnode_shift < 0) { | 277 | if (memnode_shift < 0) { |
279 | pr_err("No NUMA node hash function found. Contact maintainer\n"); | 278 | pr_err("No NUMA node hash function found. Contact maintainer\n"); |
280 | return -1; | 279 | return -1; |
@@ -284,11 +283,11 @@ int __init amd_scan_nodes(void) | |||
284 | /* use the coreid bits from early_identify_cpu */ | 283 | /* use the coreid bits from early_identify_cpu */ |
285 | for_each_node_mask(i, node_possible_map) | 284 | for_each_node_mask(i, node_possible_map) |
286 | memblock_x86_register_active_regions(i, | 285 | memblock_x86_register_active_regions(i, |
287 | nodes[i].start >> PAGE_SHIFT, | 286 | numa_nodes[i].start >> PAGE_SHIFT, |
288 | nodes[i].end >> PAGE_SHIFT); | 287 | numa_nodes[i].end >> PAGE_SHIFT); |
289 | init_memory_mapping_high(); | 288 | init_memory_mapping_high(); |
290 | for_each_node_mask(i, node_possible_map) | 289 | for_each_node_mask(i, node_possible_map) |
291 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 290 | setup_node_bootmem(i, numa_nodes[i].start, numa_nodes[i].end); |
292 | 291 | ||
293 | numa_init_array(); | 292 | numa_init_array(); |
294 | return 0; | 293 | return 0; |
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 4404e1d649a..a6b899f7ddd 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c | |||
@@ -33,6 +33,8 @@ struct memnode memnode; | |||
33 | static unsigned long __initdata nodemap_addr; | 33 | static unsigned long __initdata nodemap_addr; |
34 | static unsigned long __initdata nodemap_size; | 34 | static unsigned long __initdata nodemap_size; |
35 | 35 | ||
36 | struct bootnode numa_nodes[MAX_NUMNODES] __initdata; | ||
37 | |||
36 | /* | 38 | /* |
37 | * Given a shift value, try to populate memnodemap[] | 39 | * Given a shift value, try to populate memnodemap[] |
38 | * Returns : | 40 | * Returns : |
@@ -182,6 +184,22 @@ static void * __init early_node_mem(int nodeid, unsigned long start, | |||
182 | return NULL; | 184 | return NULL; |
183 | } | 185 | } |
184 | 186 | ||
187 | static __init void cutoff_node(int i, unsigned long start, unsigned long end) | ||
188 | { | ||
189 | struct bootnode *nd = &numa_nodes[i]; | ||
190 | |||
191 | if (nd->start < start) { | ||
192 | nd->start = start; | ||
193 | if (nd->end < nd->start) | ||
194 | nd->start = nd->end; | ||
195 | } | ||
196 | if (nd->end > end) { | ||
197 | nd->end = end; | ||
198 | if (nd->start > nd->end) | ||
199 | nd->start = nd->end; | ||
200 | } | ||
201 | } | ||
202 | |||
185 | /* Initialize bootmem allocator for a node */ | 203 | /* Initialize bootmem allocator for a node */ |
186 | void __init | 204 | void __init |
187 | setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) | 205 | setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) |
@@ -638,9 +656,15 @@ void __init initmem_init(void) | |||
638 | nodes_clear(mem_nodes_parsed); | 656 | nodes_clear(mem_nodes_parsed); |
639 | nodes_clear(node_possible_map); | 657 | nodes_clear(node_possible_map); |
640 | nodes_clear(node_online_map); | 658 | nodes_clear(node_online_map); |
659 | memset(numa_nodes, 0, sizeof(numa_nodes)); | ||
641 | 660 | ||
642 | if (numa_init[i]() < 0) | 661 | if (numa_init[i]() < 0) |
643 | continue; | 662 | continue; |
663 | |||
664 | /* clean up the node list */ | ||
665 | for (j = 0; j < MAX_NUMNODES; j++) | ||
666 | cutoff_node(j, 0, max_pfn << PAGE_SHIFT); | ||
667 | |||
644 | #ifdef CONFIG_NUMA_EMU | 668 | #ifdef CONFIG_NUMA_EMU |
645 | setup_physnodes(0, max_pfn << PAGE_SHIFT, i == 0, i == 1); | 669 | setup_physnodes(0, max_pfn << PAGE_SHIFT, i == 0, i == 1); |
646 | if (cmdline && !numa_emulation(0, max_pfn, i == 0, i == 1)) | 670 | if (cmdline && !numa_emulation(0, max_pfn, i == 0, i == 1)) |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 33e72ec4fa4..bfa4a6af5cf 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -28,7 +28,6 @@ int acpi_numa __initdata; | |||
28 | 28 | ||
29 | static struct acpi_table_slit *acpi_slit; | 29 | static struct acpi_table_slit *acpi_slit; |
30 | 30 | ||
31 | static struct bootnode nodes[MAX_NUMNODES] __initdata; | ||
32 | static struct bootnode nodes_add[MAX_NUMNODES]; | 31 | static struct bootnode nodes_add[MAX_NUMNODES]; |
33 | 32 | ||
34 | static int num_node_memblks __initdata; | 33 | static int num_node_memblks __initdata; |
@@ -55,29 +54,13 @@ static __init int conflicting_memblks(unsigned long start, unsigned long end) | |||
55 | return -1; | 54 | return -1; |
56 | } | 55 | } |
57 | 56 | ||
58 | static __init void cutoff_node(int i, unsigned long start, unsigned long end) | ||
59 | { | ||
60 | struct bootnode *nd = &nodes[i]; | ||
61 | |||
62 | if (nd->start < start) { | ||
63 | nd->start = start; | ||
64 | if (nd->end < nd->start) | ||
65 | nd->start = nd->end; | ||
66 | } | ||
67 | if (nd->end > end) { | ||
68 | nd->end = end; | ||
69 | if (nd->start > nd->end) | ||
70 | nd->start = nd->end; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | static __init void bad_srat(void) | 57 | static __init void bad_srat(void) |
75 | { | 58 | { |
76 | int i; | 59 | int i; |
77 | printk(KERN_ERR "SRAT: SRAT not used.\n"); | 60 | printk(KERN_ERR "SRAT: SRAT not used.\n"); |
78 | acpi_numa = -1; | 61 | acpi_numa = -1; |
79 | for (i = 0; i < MAX_NUMNODES; i++) { | 62 | for (i = 0; i < MAX_NUMNODES; i++) { |
80 | nodes[i].start = nodes[i].end = 0; | 63 | numa_nodes[i].start = numa_nodes[i].end = 0; |
81 | nodes_add[i].start = nodes_add[i].end = 0; | 64 | nodes_add[i].start = nodes_add[i].end = 0; |
82 | } | 65 | } |
83 | remove_all_active_ranges(); | 66 | remove_all_active_ranges(); |
@@ -276,12 +259,12 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
276 | if (i == node) { | 259 | if (i == node) { |
277 | printk(KERN_WARNING | 260 | printk(KERN_WARNING |
278 | "SRAT: Warning: PXM %d (%lx-%lx) overlaps with itself (%Lx-%Lx)\n", | 261 | "SRAT: Warning: PXM %d (%lx-%lx) overlaps with itself (%Lx-%Lx)\n", |
279 | pxm, start, end, nodes[i].start, nodes[i].end); | 262 | pxm, start, end, numa_nodes[i].start, numa_nodes[i].end); |
280 | } else if (i >= 0) { | 263 | } else if (i >= 0) { |
281 | printk(KERN_ERR | 264 | printk(KERN_ERR |
282 | "SRAT: PXM %d (%lx-%lx) overlaps with PXM %d (%Lx-%Lx)\n", | 265 | "SRAT: PXM %d (%lx-%lx) overlaps with PXM %d (%Lx-%Lx)\n", |
283 | pxm, start, end, node_to_pxm(i), | 266 | pxm, start, end, node_to_pxm(i), |
284 | nodes[i].start, nodes[i].end); | 267 | numa_nodes[i].start, numa_nodes[i].end); |
285 | bad_srat(); | 268 | bad_srat(); |
286 | return; | 269 | return; |
287 | } | 270 | } |
@@ -290,7 +273,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
290 | start, end); | 273 | start, end); |
291 | 274 | ||
292 | if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)) { | 275 | if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)) { |
293 | nd = &nodes[node]; | 276 | nd = &numa_nodes[node]; |
294 | if (!node_test_and_set(node, mem_nodes_parsed)) { | 277 | if (!node_test_and_set(node, mem_nodes_parsed)) { |
295 | nd->start = start; | 278 | nd->start = start; |
296 | nd->end = end; | 279 | nd->end = end; |
@@ -347,9 +330,8 @@ void __init acpi_get_nodes(struct bootnode *physnodes, unsigned long start, | |||
347 | int i; | 330 | int i; |
348 | 331 | ||
349 | for_each_node_mask(i, mem_nodes_parsed) { | 332 | for_each_node_mask(i, mem_nodes_parsed) { |
350 | cutoff_node(i, start, end); | 333 | physnodes[i].start = numa_nodes[i].start; |
351 | physnodes[i].start = nodes[i].start; | 334 | physnodes[i].end = numa_nodes[i].end; |
352 | physnodes[i].end = nodes[i].end; | ||
353 | } | 335 | } |
354 | } | 336 | } |
355 | #endif /* CONFIG_NUMA_EMU */ | 337 | #endif /* CONFIG_NUMA_EMU */ |
@@ -372,10 +354,6 @@ int __init acpi_scan_nodes(void) | |||
372 | if (acpi_numa <= 0) | 354 | if (acpi_numa <= 0) |
373 | return -1; | 355 | return -1; |
374 | 356 | ||
375 | /* First clean up the node list */ | ||
376 | for (i = 0; i < MAX_NUMNODES; i++) | ||
377 | cutoff_node(i, 0, max_pfn << PAGE_SHIFT); | ||
378 | |||
379 | /* | 357 | /* |
380 | * Join together blocks on the same node, holes between | 358 | * Join together blocks on the same node, holes between |
381 | * which don't overlap with memory on other nodes. | 359 | * which don't overlap with memory on other nodes. |
@@ -440,7 +418,7 @@ int __init acpi_scan_nodes(void) | |||
440 | 418 | ||
441 | /* for out of order entries in SRAT */ | 419 | /* for out of order entries in SRAT */ |
442 | sort_node_map(); | 420 | sort_node_map(); |
443 | if (!nodes_cover_memory(nodes)) { | 421 | if (!nodes_cover_memory(numa_nodes)) { |
444 | bad_srat(); | 422 | bad_srat(); |
445 | return -1; | 423 | return -1; |
446 | } | 424 | } |
@@ -449,12 +427,13 @@ int __init acpi_scan_nodes(void) | |||
449 | 427 | ||
450 | /* Finally register nodes */ | 428 | /* Finally register nodes */ |
451 | for_each_node_mask(i, node_possible_map) | 429 | for_each_node_mask(i, node_possible_map) |
452 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 430 | setup_node_bootmem(i, numa_nodes[i].start, numa_nodes[i].end); |
453 | /* Try again in case setup_node_bootmem missed one due | 431 | /* Try again in case setup_node_bootmem missed one due |
454 | to missing bootmem */ | 432 | to missing bootmem */ |
455 | for_each_node_mask(i, node_possible_map) | 433 | for_each_node_mask(i, node_possible_map) |
456 | if (!node_online(i)) | 434 | if (!node_online(i)) |
457 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 435 | setup_node_bootmem(i, numa_nodes[i].start, |
436 | numa_nodes[i].end); | ||
458 | 437 | ||
459 | for (i = 0; i < nr_cpu_ids; i++) { | 438 | for (i = 0; i < nr_cpu_ids; i++) { |
460 | int node = early_cpu_to_node(i); | 439 | int node = early_cpu_to_node(i); |
@@ -486,7 +465,7 @@ static int __init find_node_by_addr(unsigned long addr) | |||
486 | * the sake of simplicity, we only use a real node's starting | 465 | * the sake of simplicity, we only use a real node's starting |
487 | * address to determine which emulated node it appears on. | 466 | * address to determine which emulated node it appears on. |
488 | */ | 467 | */ |
489 | if (addr >= nodes[i].start && addr < nodes[i].end) { | 468 | if (addr >= numa_nodes[i].start && addr < numa_nodes[i].end) { |
490 | ret = i; | 469 | ret = i; |
491 | break; | 470 | break; |
492 | } | 471 | } |