diff options
author | Balbir Singh <balbir@linux.vnet.ibm.com> | 2007-12-07 17:37:14 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-12-20 00:11:46 -0500 |
commit | 5c3f5892a2db6757a72ce8b27cba90db06683e1d (patch) | |
tree | 891a9bd7cf09517cd291e4530748ab3ba8aee90c /arch/powerpc/mm | |
parent | 800d68c3aa0dc3e31a87f1499d63359caa77441c (diff) |
[POWERPC] Fake NUMA emulation for PowerPC
Here's a dumb simple implementation of fake NUMA nodes for PowerPC.
Fake NUMA nodes can be specified using the following command line option
numa=fake=<node range>
node range is of the format <range1>,<range2>,...<rangeN>
Each of the rangeX parameters is passed using memparse(). I find this
useful for fake NUMA emulation on my simple PowerPC machine. I've
tested it on a non-numa box with the following arguments:
numa=fake=1G
numa=fake=1G,2G
name=fake=1G,512M,2G
numa=fake=1500M,2800M mem=3500M
numa=fake=1G mem=512M
numa=fake=1G mem=1G
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r-- | arch/powerpc/mm/numa.c | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index c12adc3ddffd..1666e7d54cca 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | static int numa_enabled = 1; | 25 | static int numa_enabled = 1; |
26 | 26 | ||
27 | static char *cmdline __initdata; | ||
28 | |||
27 | static int numa_debug; | 29 | static int numa_debug; |
28 | #define dbg(args...) if (numa_debug) { printk(KERN_INFO args); } | 30 | #define dbg(args...) if (numa_debug) { printk(KERN_INFO args); } |
29 | 31 | ||
@@ -39,6 +41,43 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES]; | |||
39 | static int min_common_depth; | 41 | static int min_common_depth; |
40 | static int n_mem_addr_cells, n_mem_size_cells; | 42 | static int n_mem_addr_cells, n_mem_size_cells; |
41 | 43 | ||
44 | static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn, | ||
45 | unsigned int *nid) | ||
46 | { | ||
47 | unsigned long long mem; | ||
48 | char *p = cmdline; | ||
49 | static unsigned int fake_nid = 0; | ||
50 | static unsigned long long curr_boundary = 0; | ||
51 | |||
52 | *nid = fake_nid; | ||
53 | if (!p) | ||
54 | return 0; | ||
55 | |||
56 | mem = memparse(p, &p); | ||
57 | if (!mem) | ||
58 | return 0; | ||
59 | |||
60 | if (mem < curr_boundary) | ||
61 | return 0; | ||
62 | |||
63 | curr_boundary = mem; | ||
64 | |||
65 | if ((end_pfn << PAGE_SHIFT) > mem) { | ||
66 | /* | ||
67 | * Skip commas and spaces | ||
68 | */ | ||
69 | while (*p == ',' || *p == ' ' || *p == '\t') | ||
70 | p++; | ||
71 | |||
72 | cmdline = p; | ||
73 | fake_nid++; | ||
74 | *nid = fake_nid; | ||
75 | dbg("created new fake_node with id %d\n", fake_nid); | ||
76 | return 1; | ||
77 | } | ||
78 | return 0; | ||
79 | } | ||
80 | |||
42 | static void __cpuinit map_cpu_to_node(int cpu, int node) | 81 | static void __cpuinit map_cpu_to_node(int cpu, int node) |
43 | { | 82 | { |
44 | numa_cpu_lookup_table[cpu] = node; | 83 | numa_cpu_lookup_table[cpu] = node; |
@@ -344,12 +383,14 @@ static void __init parse_drconf_memory(struct device_node *memory) | |||
344 | if (nid == 0xffff || nid >= MAX_NUMNODES) | 383 | if (nid == 0xffff || nid >= MAX_NUMNODES) |
345 | nid = default_nid; | 384 | nid = default_nid; |
346 | } | 385 | } |
347 | node_set_online(nid); | ||
348 | 386 | ||
349 | size = numa_enforce_memory_limit(start, lmb_size); | 387 | size = numa_enforce_memory_limit(start, lmb_size); |
350 | if (!size) | 388 | if (!size) |
351 | continue; | 389 | continue; |
352 | 390 | ||
391 | fake_numa_create_new_node(((start + size) >> PAGE_SHIFT), &nid); | ||
392 | node_set_online(nid); | ||
393 | |||
353 | add_active_range(nid, start >> PAGE_SHIFT, | 394 | add_active_range(nid, start >> PAGE_SHIFT, |
354 | (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); | 395 | (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); |
355 | } | 396 | } |
@@ -429,7 +470,6 @@ new_range: | |||
429 | nid = of_node_to_nid_single(memory); | 470 | nid = of_node_to_nid_single(memory); |
430 | if (nid < 0) | 471 | if (nid < 0) |
431 | nid = default_nid; | 472 | nid = default_nid; |
432 | node_set_online(nid); | ||
433 | 473 | ||
434 | if (!(size = numa_enforce_memory_limit(start, size))) { | 474 | if (!(size = numa_enforce_memory_limit(start, size))) { |
435 | if (--ranges) | 475 | if (--ranges) |
@@ -438,6 +478,9 @@ new_range: | |||
438 | continue; | 478 | continue; |
439 | } | 479 | } |
440 | 480 | ||
481 | fake_numa_create_new_node(((start + size) >> PAGE_SHIFT), &nid); | ||
482 | node_set_online(nid); | ||
483 | |||
441 | add_active_range(nid, start >> PAGE_SHIFT, | 484 | add_active_range(nid, start >> PAGE_SHIFT, |
442 | (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); | 485 | (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); |
443 | 486 | ||
@@ -461,7 +504,7 @@ static void __init setup_nonnuma(void) | |||
461 | unsigned long top_of_ram = lmb_end_of_DRAM(); | 504 | unsigned long top_of_ram = lmb_end_of_DRAM(); |
462 | unsigned long total_ram = lmb_phys_mem_size(); | 505 | unsigned long total_ram = lmb_phys_mem_size(); |
463 | unsigned long start_pfn, end_pfn; | 506 | unsigned long start_pfn, end_pfn; |
464 | unsigned int i; | 507 | unsigned int i, nid = 0; |
465 | 508 | ||
466 | printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", | 509 | printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", |
467 | top_of_ram, total_ram); | 510 | top_of_ram, total_ram); |
@@ -471,9 +514,11 @@ static void __init setup_nonnuma(void) | |||
471 | for (i = 0; i < lmb.memory.cnt; ++i) { | 514 | for (i = 0; i < lmb.memory.cnt; ++i) { |
472 | start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; | 515 | start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; |
473 | end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); | 516 | end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); |
474 | add_active_range(0, start_pfn, end_pfn); | 517 | |
518 | fake_numa_create_new_node(end_pfn, &nid); | ||
519 | add_active_range(nid, start_pfn, end_pfn); | ||
520 | node_set_online(nid); | ||
475 | } | 521 | } |
476 | node_set_online(0); | ||
477 | } | 522 | } |
478 | 523 | ||
479 | void __init dump_numa_cpu_topology(void) | 524 | void __init dump_numa_cpu_topology(void) |
@@ -702,6 +747,10 @@ static int __init early_numa(char *p) | |||
702 | if (strstr(p, "debug")) | 747 | if (strstr(p, "debug")) |
703 | numa_debug = 1; | 748 | numa_debug = 1; |
704 | 749 | ||
750 | p = strstr(p, "fake="); | ||
751 | if (p) | ||
752 | cmdline = p + strlen("fake="); | ||
753 | |||
705 | return 0; | 754 | return 0; |
706 | } | 755 | } |
707 | early_param("numa", early_numa); | 756 | early_param("numa", early_numa); |