aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm
diff options
context:
space:
mode:
authorBalbir Singh <balbir@linux.vnet.ibm.com>2008-01-31 23:57:31 -0500
committerPaul Mackerras <paulus@samba.org>2008-02-06 19:40:19 -0500
commit1daa6d08d1257aa61f376c3cc4795660877fb9e3 (patch)
treeb53407c6dd9b3b310bdc203681ba528460612e0d /arch/powerpc/mm
parent7dbb922cea70897dd0e76c6cf8a300b061ca2531 (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 the patch useful for fake NUMA emulation on my simple PowerPC machine. I've tested it on a numa box with the following arguments numa=fake=512M numa=fake=512M,768M numa=fake=256M,512M mem=512M numa=fake=1G mem=768M numa=fake= without any numa= argument The other side-effect introduced by this patch is that; in the case where we don't have NUMA information, we now set a node online after adding each LMB. This node could very well be node 0, but in the case that we enable fake NUMA nodes, when we cross node boundaries, we need to set the new node online. Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r--arch/powerpc/mm/numa.c66
1 files changed, 63 insertions, 3 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index c12adc3ddffd..e9139d267ea4 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,53 @@ 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;
50 static unsigned long long curr_boundary;
51
52 /*
53 * Modify node id, iff we started creating NUMA nodes
54 * We want to continue from where we left of the last time
55 */
56 if (fake_nid)
57 *nid = fake_nid;
58 /*
59 * In case there are no more arguments to parse, the
60 * node_id should be the same as the last fake node id
61 * (we've handled this above).
62 */
63 if (!p)
64 return 0;
65
66 mem = memparse(p, &p);
67 if (!mem)
68 return 0;
69
70 if (mem < curr_boundary)
71 return 0;
72
73 curr_boundary = mem;
74
75 if ((end_pfn << PAGE_SHIFT) > mem) {
76 /*
77 * Skip commas and spaces
78 */
79 while (*p == ',' || *p == ' ' || *p == '\t')
80 p++;
81
82 cmdline = p;
83 fake_nid++;
84 *nid = fake_nid;
85 dbg("created new fake_node with id %d\n", fake_nid);
86 return 1;
87 }
88 return 0;
89}
90
42static void __cpuinit map_cpu_to_node(int cpu, int node) 91static void __cpuinit map_cpu_to_node(int cpu, int node)
43{ 92{
44 numa_cpu_lookup_table[cpu] = node; 93 numa_cpu_lookup_table[cpu] = node;
@@ -344,6 +393,9 @@ static void __init parse_drconf_memory(struct device_node *memory)
344 if (nid == 0xffff || nid >= MAX_NUMNODES) 393 if (nid == 0xffff || nid >= MAX_NUMNODES)
345 nid = default_nid; 394 nid = default_nid;
346 } 395 }
396
397 fake_numa_create_new_node(((start + lmb_size) >> PAGE_SHIFT),
398 &nid);
347 node_set_online(nid); 399 node_set_online(nid);
348 400
349 size = numa_enforce_memory_limit(start, lmb_size); 401 size = numa_enforce_memory_limit(start, lmb_size);
@@ -429,6 +481,8 @@ new_range:
429 nid = of_node_to_nid_single(memory); 481 nid = of_node_to_nid_single(memory);
430 if (nid < 0) 482 if (nid < 0)
431 nid = default_nid; 483 nid = default_nid;
484
485 fake_numa_create_new_node(((start + size) >> PAGE_SHIFT), &nid);
432 node_set_online(nid); 486 node_set_online(nid);
433 487
434 if (!(size = numa_enforce_memory_limit(start, size))) { 488 if (!(size = numa_enforce_memory_limit(start, size))) {
@@ -461,7 +515,7 @@ static void __init setup_nonnuma(void)
461 unsigned long top_of_ram = lmb_end_of_DRAM(); 515 unsigned long top_of_ram = lmb_end_of_DRAM();
462 unsigned long total_ram = lmb_phys_mem_size(); 516 unsigned long total_ram = lmb_phys_mem_size();
463 unsigned long start_pfn, end_pfn; 517 unsigned long start_pfn, end_pfn;
464 unsigned int i; 518 unsigned int i, nid = 0;
465 519
466 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", 520 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
467 top_of_ram, total_ram); 521 top_of_ram, total_ram);
@@ -471,9 +525,11 @@ static void __init setup_nonnuma(void)
471 for (i = 0; i < lmb.memory.cnt; ++i) { 525 for (i = 0; i < lmb.memory.cnt; ++i) {
472 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; 526 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
473 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); 527 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
474 add_active_range(0, start_pfn, end_pfn); 528
529 fake_numa_create_new_node(end_pfn, &nid);
530 add_active_range(nid, start_pfn, end_pfn);
531 node_set_online(nid);
475 } 532 }
476 node_set_online(0);
477} 533}
478 534
479void __init dump_numa_cpu_topology(void) 535void __init dump_numa_cpu_topology(void)
@@ -702,6 +758,10 @@ static int __init early_numa(char *p)
702 if (strstr(p, "debug")) 758 if (strstr(p, "debug"))
703 numa_debug = 1; 759 numa_debug = 1;
704 760
761 p = strstr(p, "fake=");
762 if (p)
763 cmdline = p + strlen("fake=");
764
705 return 0; 765 return 0;
706} 766}
707early_param("numa", early_numa); 767early_param("numa", early_numa);