diff options
-rw-r--r-- | arch/powerpc/mm/numa.c | 66 |
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 | ||
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,53 @@ 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; | ||
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 | |||
42 | static void __cpuinit map_cpu_to_node(int cpu, int node) | 91 | static 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 | ||
479 | void __init dump_numa_cpu_topology(void) | 535 | void __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 | } |
707 | early_param("numa", early_numa); | 767 | early_param("numa", early_numa); |