diff options
author | Mel Gorman <mel@csn.ul.ie> | 2006-09-27 04:49:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-27 11:26:11 -0400 |
commit | c67c3cb4c99fb2ee63c8733943c353d745f45b84 (patch) | |
tree | 5628da22a723aab1d11dfbedda264f3f65addc21 /arch/powerpc/mm/numa.c | |
parent | c713216deebd95d2b0ab38fef8bb2361c0180c2d (diff) |
[PATCH] Have Power use add_active_range() and free_area_init_nodes()
Size zones and holes in an architecture independent manner for Power.
[judith@osdl.org: build fix]
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
Cc: Dave Hansen <haveblue@us.ibm.com>
Cc: Andy Whitcroft <apw@shadowen.org>
Cc: Andi Kleen <ak@muc.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: "Keith Mannthey" <kmannth@gmail.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Yasunori Goto <y-goto@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/powerpc/mm/numa.c')
-rw-r--r-- | arch/powerpc/mm/numa.c | 159 |
1 files changed, 16 insertions, 143 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 6c0f1c7d83e5..43c272075e1a 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -39,96 +39,6 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES]; | |||
39 | static int min_common_depth; | 39 | static int min_common_depth; |
40 | static int n_mem_addr_cells, n_mem_size_cells; | 40 | static int n_mem_addr_cells, n_mem_size_cells; |
41 | 41 | ||
42 | /* | ||
43 | * We need somewhere to store start/end/node for each region until we have | ||
44 | * allocated the real node_data structures. | ||
45 | */ | ||
46 | #define MAX_REGIONS (MAX_LMB_REGIONS*2) | ||
47 | static struct { | ||
48 | unsigned long start_pfn; | ||
49 | unsigned long end_pfn; | ||
50 | int nid; | ||
51 | } init_node_data[MAX_REGIONS] __initdata; | ||
52 | |||
53 | int __init early_pfn_to_nid(unsigned long pfn) | ||
54 | { | ||
55 | unsigned int i; | ||
56 | |||
57 | for (i = 0; init_node_data[i].end_pfn; i++) { | ||
58 | unsigned long start_pfn = init_node_data[i].start_pfn; | ||
59 | unsigned long end_pfn = init_node_data[i].end_pfn; | ||
60 | |||
61 | if ((start_pfn <= pfn) && (pfn < end_pfn)) | ||
62 | return init_node_data[i].nid; | ||
63 | } | ||
64 | |||
65 | return -1; | ||
66 | } | ||
67 | |||
68 | void __init add_region(unsigned int nid, unsigned long start_pfn, | ||
69 | unsigned long pages) | ||
70 | { | ||
71 | unsigned int i; | ||
72 | |||
73 | dbg("add_region nid %d start_pfn 0x%lx pages 0x%lx\n", | ||
74 | nid, start_pfn, pages); | ||
75 | |||
76 | for (i = 0; init_node_data[i].end_pfn; i++) { | ||
77 | if (init_node_data[i].nid != nid) | ||
78 | continue; | ||
79 | if (init_node_data[i].end_pfn == start_pfn) { | ||
80 | init_node_data[i].end_pfn += pages; | ||
81 | return; | ||
82 | } | ||
83 | if (init_node_data[i].start_pfn == (start_pfn + pages)) { | ||
84 | init_node_data[i].start_pfn -= pages; | ||
85 | return; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Leave last entry NULL so we dont iterate off the end (we use | ||
91 | * entry.end_pfn to terminate the walk). | ||
92 | */ | ||
93 | if (i >= (MAX_REGIONS - 1)) { | ||
94 | printk(KERN_ERR "WARNING: too many memory regions in " | ||
95 | "numa code, truncating\n"); | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | init_node_data[i].start_pfn = start_pfn; | ||
100 | init_node_data[i].end_pfn = start_pfn + pages; | ||
101 | init_node_data[i].nid = nid; | ||
102 | } | ||
103 | |||
104 | /* We assume init_node_data has no overlapping regions */ | ||
105 | void __init get_region(unsigned int nid, unsigned long *start_pfn, | ||
106 | unsigned long *end_pfn, unsigned long *pages_present) | ||
107 | { | ||
108 | unsigned int i; | ||
109 | |||
110 | *start_pfn = -1UL; | ||
111 | *end_pfn = *pages_present = 0; | ||
112 | |||
113 | for (i = 0; init_node_data[i].end_pfn; i++) { | ||
114 | if (init_node_data[i].nid != nid) | ||
115 | continue; | ||
116 | |||
117 | *pages_present += init_node_data[i].end_pfn - | ||
118 | init_node_data[i].start_pfn; | ||
119 | |||
120 | if (init_node_data[i].start_pfn < *start_pfn) | ||
121 | *start_pfn = init_node_data[i].start_pfn; | ||
122 | |||
123 | if (init_node_data[i].end_pfn > *end_pfn) | ||
124 | *end_pfn = init_node_data[i].end_pfn; | ||
125 | } | ||
126 | |||
127 | /* We didnt find a matching region, return start/end as 0 */ | ||
128 | if (*start_pfn == -1UL) | ||
129 | *start_pfn = 0; | ||
130 | } | ||
131 | |||
132 | static void __cpuinit map_cpu_to_node(int cpu, int node) | 42 | static void __cpuinit map_cpu_to_node(int cpu, int node) |
133 | { | 43 | { |
134 | numa_cpu_lookup_table[cpu] = node; | 44 | numa_cpu_lookup_table[cpu] = node; |
@@ -468,8 +378,8 @@ new_range: | |||
468 | continue; | 378 | continue; |
469 | } | 379 | } |
470 | 380 | ||
471 | add_region(nid, start >> PAGE_SHIFT, | 381 | add_active_range(nid, start >> PAGE_SHIFT, |
472 | size >> PAGE_SHIFT); | 382 | (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); |
473 | 383 | ||
474 | if (--ranges) | 384 | if (--ranges) |
475 | goto new_range; | 385 | goto new_range; |
@@ -482,6 +392,7 @@ static void __init setup_nonnuma(void) | |||
482 | { | 392 | { |
483 | unsigned long top_of_ram = lmb_end_of_DRAM(); | 393 | unsigned long top_of_ram = lmb_end_of_DRAM(); |
484 | unsigned long total_ram = lmb_phys_mem_size(); | 394 | unsigned long total_ram = lmb_phys_mem_size(); |
395 | unsigned long start_pfn, end_pfn; | ||
485 | unsigned int i; | 396 | unsigned int i; |
486 | 397 | ||
487 | printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", | 398 | printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", |
@@ -489,9 +400,11 @@ static void __init setup_nonnuma(void) | |||
489 | printk(KERN_DEBUG "Memory hole size: %ldMB\n", | 400 | printk(KERN_DEBUG "Memory hole size: %ldMB\n", |
490 | (top_of_ram - total_ram) >> 20); | 401 | (top_of_ram - total_ram) >> 20); |
491 | 402 | ||
492 | for (i = 0; i < lmb.memory.cnt; ++i) | 403 | for (i = 0; i < lmb.memory.cnt; ++i) { |
493 | add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT, | 404 | start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; |
494 | lmb_size_pages(&lmb.memory, i)); | 405 | end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); |
406 | add_active_range(0, start_pfn, end_pfn); | ||
407 | } | ||
495 | node_set_online(0); | 408 | node_set_online(0); |
496 | } | 409 | } |
497 | 410 | ||
@@ -630,11 +543,11 @@ void __init do_init_bootmem(void) | |||
630 | (void *)(unsigned long)boot_cpuid); | 543 | (void *)(unsigned long)boot_cpuid); |
631 | 544 | ||
632 | for_each_online_node(nid) { | 545 | for_each_online_node(nid) { |
633 | unsigned long start_pfn, end_pfn, pages_present; | 546 | unsigned long start_pfn, end_pfn; |
634 | unsigned long bootmem_paddr; | 547 | unsigned long bootmem_paddr; |
635 | unsigned long bootmap_pages; | 548 | unsigned long bootmap_pages; |
636 | 549 | ||
637 | get_region(nid, &start_pfn, &end_pfn, &pages_present); | 550 | get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); |
638 | 551 | ||
639 | /* Allocate the node structure node local if possible */ | 552 | /* Allocate the node structure node local if possible */ |
640 | NODE_DATA(nid) = careful_allocation(nid, | 553 | NODE_DATA(nid) = careful_allocation(nid, |
@@ -667,19 +580,7 @@ void __init do_init_bootmem(void) | |||
667 | init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, | 580 | init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, |
668 | start_pfn, end_pfn); | 581 | start_pfn, end_pfn); |
669 | 582 | ||
670 | /* Add free regions on this node */ | 583 | free_bootmem_with_active_regions(nid, end_pfn); |
671 | for (i = 0; init_node_data[i].end_pfn; i++) { | ||
672 | unsigned long start, end; | ||
673 | |||
674 | if (init_node_data[i].nid != nid) | ||
675 | continue; | ||
676 | |||
677 | start = init_node_data[i].start_pfn << PAGE_SHIFT; | ||
678 | end = init_node_data[i].end_pfn << PAGE_SHIFT; | ||
679 | |||
680 | dbg("free_bootmem %lx %lx\n", start, end - start); | ||
681 | free_bootmem_node(NODE_DATA(nid), start, end - start); | ||
682 | } | ||
683 | 584 | ||
684 | /* Mark reserved regions on this node */ | 585 | /* Mark reserved regions on this node */ |
685 | for (i = 0; i < lmb.reserved.cnt; i++) { | 586 | for (i = 0; i < lmb.reserved.cnt; i++) { |
@@ -710,44 +611,16 @@ void __init do_init_bootmem(void) | |||
710 | } | 611 | } |
711 | } | 612 | } |
712 | 613 | ||
713 | /* Add regions into sparsemem */ | 614 | sparse_memory_present_with_active_regions(nid); |
714 | for (i = 0; init_node_data[i].end_pfn; i++) { | ||
715 | unsigned long start, end; | ||
716 | |||
717 | if (init_node_data[i].nid != nid) | ||
718 | continue; | ||
719 | |||
720 | start = init_node_data[i].start_pfn; | ||
721 | end = init_node_data[i].end_pfn; | ||
722 | |||
723 | memory_present(nid, start, end); | ||
724 | } | ||
725 | } | 615 | } |
726 | } | 616 | } |
727 | 617 | ||
728 | void __init paging_init(void) | 618 | void __init paging_init(void) |
729 | { | 619 | { |
730 | unsigned long zones_size[MAX_NR_ZONES]; | 620 | unsigned long max_zone_pfns[MAX_NR_ZONES] = { |
731 | unsigned long zholes_size[MAX_NR_ZONES]; | 621 | lmb_end_of_DRAM() >> PAGE_SHIFT |
732 | int nid; | 622 | }; |
733 | 623 | free_area_init_nodes(max_zone_pfns); | |
734 | memset(zones_size, 0, sizeof(zones_size)); | ||
735 | memset(zholes_size, 0, sizeof(zholes_size)); | ||
736 | |||
737 | for_each_online_node(nid) { | ||
738 | unsigned long start_pfn, end_pfn, pages_present; | ||
739 | |||
740 | get_region(nid, &start_pfn, &end_pfn, &pages_present); | ||
741 | |||
742 | zones_size[ZONE_DMA] = end_pfn - start_pfn; | ||
743 | zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - pages_present; | ||
744 | |||
745 | dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid, | ||
746 | zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]); | ||
747 | |||
748 | free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn, | ||
749 | zholes_size); | ||
750 | } | ||
751 | } | 624 | } |
752 | 625 | ||
753 | static int __init early_numa(char *p) | 626 | static int __init early_numa(char *p) |