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 | ec8cf29b1d39aeb6ef98bc589f0c9a33a8f94c49 (patch) | |
tree | 096c8f6b23944e000628d245fd43719cd7a1b104 /arch/x86/mm | |
parent | ffe77a4605fb2588f8666850ad3e3b196241658f (diff) |
x86-64, NUMA: Use common {cpu|mem}_nodes_parsed
ACPI and amd are using separate nodes_parsed masks. Add
{cpu|mem}_nodes_parsed and use them in all NUMA init methods.
Initialization of the masks and building node_possible_map are now
handled commonly by initmem_init().
dummy_numa_init() is updated to set node 0 on both masks. While at
it, move the info messages from scan to init.
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/mm')
-rw-r--r-- | arch/x86/mm/amdtopology_64.c | 10 | ||||
-rw-r--r-- | arch/x86/mm/numa_64.c | 25 | ||||
-rw-r--r-- | arch/x86/mm/srat_64.c | 17 |
3 files changed, 28 insertions, 24 deletions
diff --git a/arch/x86/mm/amdtopology_64.c b/arch/x86/mm/amdtopology_64.c index 655ccffc6ee5..4f822a247125 100644 --- a/arch/x86/mm/amdtopology_64.c +++ b/arch/x86/mm/amdtopology_64.c | |||
@@ -28,7 +28,6 @@ | |||
28 | 28 | ||
29 | static struct bootnode __initdata nodes[8]; | 29 | static struct bootnode __initdata nodes[8]; |
30 | static unsigned char __initdata nodeids[8]; | 30 | static unsigned char __initdata nodeids[8]; |
31 | static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE; | ||
32 | 31 | ||
33 | static __init int find_northbridge(void) | 32 | static __init int find_northbridge(void) |
34 | { | 33 | { |
@@ -123,7 +122,7 @@ int __init amd_numa_init(void) | |||
123 | nodeid, (base >> 8) & 3, (limit >> 8) & 3); | 122 | nodeid, (base >> 8) & 3, (limit >> 8) & 3); |
124 | return -EINVAL; | 123 | return -EINVAL; |
125 | } | 124 | } |
126 | if (node_isset(nodeid, nodes_parsed)) { | 125 | if (node_isset(nodeid, mem_nodes_parsed)) { |
127 | pr_info("Node %d already present, skipping\n", | 126 | pr_info("Node %d already present, skipping\n", |
128 | nodeid); | 127 | nodeid); |
129 | continue; | 128 | continue; |
@@ -173,7 +172,8 @@ int __init amd_numa_init(void) | |||
173 | 172 | ||
174 | prevbase = base; | 173 | prevbase = base; |
175 | 174 | ||
176 | node_set(nodeid, nodes_parsed); | 175 | node_set(nodeid, mem_nodes_parsed); |
176 | node_set(nodeid, cpu_nodes_parsed); | ||
177 | } | 177 | } |
178 | 178 | ||
179 | if (!found) | 179 | if (!found) |
@@ -190,7 +190,7 @@ void __init amd_get_nodes(struct bootnode *physnodes) | |||
190 | { | 190 | { |
191 | int i; | 191 | int i; |
192 | 192 | ||
193 | for_each_node_mask(i, nodes_parsed) { | 193 | for_each_node_mask(i, mem_nodes_parsed) { |
194 | physnodes[i].start = nodes[i].start; | 194 | physnodes[i].start = nodes[i].start; |
195 | physnodes[i].end = nodes[i].end; | 195 | physnodes[i].end = nodes[i].end; |
196 | } | 196 | } |
@@ -258,8 +258,6 @@ int __init amd_scan_nodes(void) | |||
258 | unsigned int apicid_base; | 258 | unsigned int apicid_base; |
259 | int i; | 259 | int i; |
260 | 260 | ||
261 | BUG_ON(nodes_empty(nodes_parsed)); | ||
262 | node_possible_map = nodes_parsed; | ||
263 | memnode_shift = compute_hash_shift(nodes, 8, NULL); | 261 | memnode_shift = compute_hash_shift(nodes, 8, NULL); |
264 | if (memnode_shift < 0) { | 262 | if (memnode_shift < 0) { |
265 | pr_err("No NUMA node hash function found. Contact maintainer\n"); | 263 | pr_err("No NUMA node hash function found. Contact maintainer\n"); |
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index c984e3431cc7..4404e1d649ac 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c | |||
@@ -25,6 +25,9 @@ | |||
25 | struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; | 25 | struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; |
26 | EXPORT_SYMBOL(node_data); | 26 | EXPORT_SYMBOL(node_data); |
27 | 27 | ||
28 | nodemask_t cpu_nodes_parsed __initdata; | ||
29 | nodemask_t mem_nodes_parsed __initdata; | ||
30 | |||
28 | struct memnode memnode; | 31 | struct memnode memnode; |
29 | 32 | ||
30 | static unsigned long __initdata nodemap_addr; | 33 | static unsigned long __initdata nodemap_addr; |
@@ -582,22 +585,23 @@ static int __init numa_emulation(unsigned long start_pfn, | |||
582 | 585 | ||
583 | static int dummy_numa_init(void) | 586 | static int dummy_numa_init(void) |
584 | { | 587 | { |
585 | return 0; | ||
586 | } | ||
587 | |||
588 | static int dummy_scan_nodes(void) | ||
589 | { | ||
590 | printk(KERN_INFO "%s\n", | 588 | printk(KERN_INFO "%s\n", |
591 | numa_off ? "NUMA turned off" : "No NUMA configuration found"); | 589 | numa_off ? "NUMA turned off" : "No NUMA configuration found"); |
592 | printk(KERN_INFO "Faking a node at %016lx-%016lx\n", | 590 | printk(KERN_INFO "Faking a node at %016lx-%016lx\n", |
593 | 0LU, max_pfn << PAGE_SHIFT); | 591 | 0LU, max_pfn << PAGE_SHIFT); |
594 | 592 | ||
593 | node_set(0, cpu_nodes_parsed); | ||
594 | node_set(0, mem_nodes_parsed); | ||
595 | |||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static int dummy_scan_nodes(void) | ||
600 | { | ||
595 | /* setup dummy node covering all memory */ | 601 | /* setup dummy node covering all memory */ |
596 | memnode_shift = 63; | 602 | memnode_shift = 63; |
597 | memnodemap = memnode.embedded_map; | 603 | memnodemap = memnode.embedded_map; |
598 | memnodemap[0] = 0; | 604 | memnodemap[0] = 0; |
599 | node_set_online(0); | ||
600 | node_set(0, node_possible_map); | ||
601 | memblock_x86_register_active_regions(0, 0, max_pfn); | 605 | memblock_x86_register_active_regions(0, 0, max_pfn); |
602 | init_memory_mapping_high(); | 606 | init_memory_mapping_high(); |
603 | setup_node_bootmem(0, 0, max_pfn << PAGE_SHIFT); | 607 | setup_node_bootmem(0, 0, max_pfn << PAGE_SHIFT); |
@@ -630,6 +634,8 @@ void __init initmem_init(void) | |||
630 | for (j = 0; j < MAX_LOCAL_APIC; j++) | 634 | for (j = 0; j < MAX_LOCAL_APIC; j++) |
631 | set_apicid_to_node(j, NUMA_NO_NODE); | 635 | set_apicid_to_node(j, NUMA_NO_NODE); |
632 | 636 | ||
637 | nodes_clear(cpu_nodes_parsed); | ||
638 | nodes_clear(mem_nodes_parsed); | ||
633 | nodes_clear(node_possible_map); | 639 | nodes_clear(node_possible_map); |
634 | nodes_clear(node_online_map); | 640 | nodes_clear(node_online_map); |
635 | 641 | ||
@@ -643,6 +649,11 @@ void __init initmem_init(void) | |||
643 | nodes_clear(node_possible_map); | 649 | nodes_clear(node_possible_map); |
644 | nodes_clear(node_online_map); | 650 | nodes_clear(node_online_map); |
645 | #endif | 651 | #endif |
652 | /* Account for nodes with cpus and no memory */ | ||
653 | nodes_or(node_possible_map, mem_nodes_parsed, cpu_nodes_parsed); | ||
654 | if (WARN_ON(nodes_empty(node_possible_map))) | ||
655 | continue; | ||
656 | |||
646 | if (!scan_nodes[i]()) | 657 | if (!scan_nodes[i]()) |
647 | return; | 658 | return; |
648 | } | 659 | } |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 597e011cfb51..33e72ec4fa4c 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -28,8 +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 nodemask_t nodes_parsed __initdata; | ||
32 | static nodemask_t cpu_nodes_parsed __initdata; | ||
33 | static struct bootnode nodes[MAX_NUMNODES] __initdata; | 31 | static struct bootnode nodes[MAX_NUMNODES] __initdata; |
34 | static struct bootnode nodes_add[MAX_NUMNODES]; | 32 | static struct bootnode nodes_add[MAX_NUMNODES]; |
35 | 33 | ||
@@ -293,7 +291,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
293 | 291 | ||
294 | if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)) { | 292 | if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)) { |
295 | nd = &nodes[node]; | 293 | nd = &nodes[node]; |
296 | if (!node_test_and_set(node, nodes_parsed)) { | 294 | if (!node_test_and_set(node, mem_nodes_parsed)) { |
297 | nd->start = start; | 295 | nd->start = start; |
298 | nd->end = end; | 296 | nd->end = end; |
299 | } else { | 297 | } else { |
@@ -319,7 +317,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes) | |||
319 | unsigned long pxmram, e820ram; | 317 | unsigned long pxmram, e820ram; |
320 | 318 | ||
321 | pxmram = 0; | 319 | pxmram = 0; |
322 | for_each_node_mask(i, nodes_parsed) { | 320 | for_each_node_mask(i, mem_nodes_parsed) { |
323 | unsigned long s = nodes[i].start >> PAGE_SHIFT; | 321 | unsigned long s = nodes[i].start >> PAGE_SHIFT; |
324 | unsigned long e = nodes[i].end >> PAGE_SHIFT; | 322 | unsigned long e = nodes[i].end >> PAGE_SHIFT; |
325 | pxmram += e - s; | 323 | pxmram += e - s; |
@@ -348,7 +346,7 @@ void __init acpi_get_nodes(struct bootnode *physnodes, unsigned long start, | |||
348 | { | 346 | { |
349 | int i; | 347 | int i; |
350 | 348 | ||
351 | for_each_node_mask(i, nodes_parsed) { | 349 | for_each_node_mask(i, mem_nodes_parsed) { |
352 | cutoff_node(i, start, end); | 350 | cutoff_node(i, start, end); |
353 | physnodes[i].start = nodes[i].start; | 351 | physnodes[i].start = nodes[i].start; |
354 | physnodes[i].end = nodes[i].end; | 352 | physnodes[i].end = nodes[i].end; |
@@ -449,9 +447,6 @@ int __init acpi_scan_nodes(void) | |||
449 | 447 | ||
450 | init_memory_mapping_high(); | 448 | init_memory_mapping_high(); |
451 | 449 | ||
452 | /* Account for nodes with cpus and no memory */ | ||
453 | nodes_or(node_possible_map, nodes_parsed, cpu_nodes_parsed); | ||
454 | |||
455 | /* Finally register nodes */ | 450 | /* Finally register nodes */ |
456 | for_each_node_mask(i, node_possible_map) | 451 | for_each_node_mask(i, node_possible_map) |
457 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 452 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); |
@@ -485,7 +480,7 @@ static int __init find_node_by_addr(unsigned long addr) | |||
485 | int ret = NUMA_NO_NODE; | 480 | int ret = NUMA_NO_NODE; |
486 | int i; | 481 | int i; |
487 | 482 | ||
488 | for_each_node_mask(i, nodes_parsed) { | 483 | for_each_node_mask(i, mem_nodes_parsed) { |
489 | /* | 484 | /* |
490 | * Find the real node that this emulated node appears on. For | 485 | * Find the real node that this emulated node appears on. For |
491 | * the sake of simplicity, we only use a real node's starting | 486 | * the sake of simplicity, we only use a real node's starting |
@@ -545,10 +540,10 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes) | |||
545 | __acpi_map_pxm_to_node(fake_node_to_pxm_map[i], i); | 540 | __acpi_map_pxm_to_node(fake_node_to_pxm_map[i], i); |
546 | memcpy(__apicid_to_node, fake_apicid_to_node, sizeof(__apicid_to_node)); | 541 | memcpy(__apicid_to_node, fake_apicid_to_node, sizeof(__apicid_to_node)); |
547 | 542 | ||
548 | nodes_clear(nodes_parsed); | 543 | nodes_clear(mem_nodes_parsed); |
549 | for (i = 0; i < num_nodes; i++) | 544 | for (i = 0; i < num_nodes; i++) |
550 | if (fake_nodes[i].start != fake_nodes[i].end) | 545 | if (fake_nodes[i].start != fake_nodes[i].end) |
551 | node_set(i, nodes_parsed); | 546 | node_set(i, mem_nodes_parsed); |
552 | } | 547 | } |
553 | 548 | ||
554 | static int null_slit_node_compare(int a, int b) | 549 | static int null_slit_node_compare(int a, int b) |