aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBalbir Singh <balbir@linux.vnet.ibm.com>2007-12-07 17:37:14 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-20 00:11:46 -0500
commit5c3f5892a2db6757a72ce8b27cba90db06683e1d (patch)
tree891a9bd7cf09517cd291e4530748ab3ba8aee90c
parent800d68c3aa0dc3e31a87f1499d63359caa77441c (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>
-rw-r--r--arch/powerpc/mm/numa.c59
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
25static int numa_enabled = 1; 25static int numa_enabled = 1;
26 26
27static char *cmdline __initdata;
28
27static int numa_debug; 29static 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];
39static int min_common_depth; 41static int min_common_depth;
40static int n_mem_addr_cells, n_mem_size_cells; 42static int n_mem_addr_cells, n_mem_size_cells;
41 43
44static 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
42static void __cpuinit map_cpu_to_node(int cpu, int node) 81static 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
479void __init dump_numa_cpu_topology(void) 524void __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}
707early_param("numa", early_numa); 756early_param("numa", early_numa);