aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-02-16 06:13:07 -0500
committerTejun Heo <tj@kernel.org>2011-02-16 06:13:07 -0500
commit206e42087a037fa3adca8908fd318a0cb64d4dee (patch)
tree044cc262b03c62064a65d13b119b6f73da5c22f4 /arch/x86
parent45fe6c78c4ccc384044d1b4877eebe7acf359e76 (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.h1
-rw-r--r--arch/x86/mm/amdtopology_64.c19
-rw-r--r--arch/x86/mm/numa_64.c24
-rw-r--r--arch/x86/mm/srat_64.c43
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
30extern nodemask_t cpu_nodes_parsed __initdata; 30extern nodemask_t cpu_nodes_parsed __initdata;
31extern nodemask_t mem_nodes_parsed __initdata; 31extern nodemask_t mem_nodes_parsed __initdata;
32extern struct bootnode numa_nodes[MAX_NUMNODES] __initdata;
32 33
33extern int __cpuinit numa_cpu_node(int cpu); 34extern 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
29static struct bootnode __initdata nodes[8];
30static unsigned char __initdata nodeids[8]; 29static unsigned char __initdata nodeids[8];
31 30
32static __init int find_northbridge(void) 31static __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;
33static unsigned long __initdata nodemap_addr; 33static unsigned long __initdata nodemap_addr;
34static unsigned long __initdata nodemap_size; 34static unsigned long __initdata nodemap_size;
35 35
36struct 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
187static __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 */
186void __init 204void __init
187setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) 205setup_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
29static struct acpi_table_slit *acpi_slit; 29static struct acpi_table_slit *acpi_slit;
30 30
31static struct bootnode nodes[MAX_NUMNODES] __initdata;
32static struct bootnode nodes_add[MAX_NUMNODES]; 31static struct bootnode nodes_add[MAX_NUMNODES];
33 32
34static int num_node_memblks __initdata; 33static 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
58static __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
74static __init void bad_srat(void) 57static __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 }