aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/mm/numa.c108
1 files changed, 80 insertions, 28 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index be05457631d4..6cf5c71c431f 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -89,6 +89,46 @@ static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
89 return 0; 89 return 0;
90} 90}
91 91
92/*
93 * get_active_region_work_fn - A helper function for get_node_active_region
94 * Returns datax set to the start_pfn and end_pfn if they contain
95 * the initial value of datax->start_pfn between them
96 * @start_pfn: start page(inclusive) of region to check
97 * @end_pfn: end page(exclusive) of region to check
98 * @datax: comes in with ->start_pfn set to value to search for and
99 * goes out with active range if it contains it
100 * Returns 1 if search value is in range else 0
101 */
102static int __init get_active_region_work_fn(unsigned long start_pfn,
103 unsigned long end_pfn, void *datax)
104{
105 struct node_active_region *data;
106 data = (struct node_active_region *)datax;
107
108 if (start_pfn <= data->start_pfn && end_pfn > data->start_pfn) {
109 data->start_pfn = start_pfn;
110 data->end_pfn = end_pfn;
111 return 1;
112 }
113 return 0;
114
115}
116
117/*
118 * get_node_active_region - Return active region containing start_pfn
119 * @start_pfn: The page to return the region for.
120 * @node_ar: Returned set to the active region containing start_pfn
121 */
122static void __init get_node_active_region(unsigned long start_pfn,
123 struct node_active_region *node_ar)
124{
125 int nid = early_pfn_to_nid(start_pfn);
126
127 node_ar->nid = nid;
128 node_ar->start_pfn = start_pfn;
129 work_with_active_regions(nid, get_active_region_work_fn, node_ar);
130}
131
92static void __cpuinit map_cpu_to_node(int cpu, int node) 132static void __cpuinit map_cpu_to_node(int cpu, int node)
93{ 133{
94 numa_cpu_lookup_table[cpu] = node; 134 numa_cpu_lookup_table[cpu] = node;
@@ -882,38 +922,50 @@ void __init do_init_bootmem(void)
882 start_pfn, end_pfn); 922 start_pfn, end_pfn);
883 923
884 free_bootmem_with_active_regions(nid, end_pfn); 924 free_bootmem_with_active_regions(nid, end_pfn);
925 }
885 926
886 /* Mark reserved regions on this node */ 927 /* Mark reserved regions */
887 for (i = 0; i < lmb.reserved.cnt; i++) { 928 for (i = 0; i < lmb.reserved.cnt; i++) {
888 unsigned long physbase = lmb.reserved.region[i].base; 929 unsigned long physbase = lmb.reserved.region[i].base;
889 unsigned long size = lmb.reserved.region[i].size; 930 unsigned long size = lmb.reserved.region[i].size;
890 unsigned long start_paddr = start_pfn << PAGE_SHIFT; 931 unsigned long start_pfn = physbase >> PAGE_SHIFT;
891 unsigned long end_paddr = end_pfn << PAGE_SHIFT; 932 unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT);
892 933 struct node_active_region node_ar;
893 if (early_pfn_to_nid(physbase >> PAGE_SHIFT) != nid && 934
894 early_pfn_to_nid((physbase+size-1) >> PAGE_SHIFT) != nid) 935 get_node_active_region(start_pfn, &node_ar);
895 continue; 936 while (start_pfn < end_pfn) {
896 937 /*
897 if (physbase < end_paddr && 938 * if reserved region extends past active region
898 (physbase+size) > start_paddr) { 939 * then trim size to active region
899 /* overlaps */ 940 */
900 if (physbase < start_paddr) { 941 if (end_pfn > node_ar.end_pfn)
901 size -= start_paddr - physbase; 942 size = (node_ar.end_pfn << PAGE_SHIFT)
902 physbase = start_paddr; 943 - (start_pfn << PAGE_SHIFT);
903 } 944 dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, size,
904 945 node_ar.nid);
905 if (size > end_paddr - physbase) 946 reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
906 size = end_paddr - physbase; 947 size, BOOTMEM_DEFAULT);
907 948 /*
908 dbg("reserve_bootmem %lx %lx\n", physbase, 949 * if reserved region is contained in the active region
909 size); 950 * then done.
910 reserve_bootmem_node(NODE_DATA(nid), physbase, 951 */
911 size, BOOTMEM_DEFAULT); 952 if (end_pfn <= node_ar.end_pfn)
912 } 953 break;
954
955 /*
956 * reserved region extends past the active region
957 * get next active region that contains this
958 * reserved region
959 */
960 start_pfn = node_ar.end_pfn;
961 physbase = start_pfn << PAGE_SHIFT;
962 get_node_active_region(start_pfn, &node_ar);
913 } 963 }
914 964
915 sparse_memory_present_with_active_regions(nid);
916 } 965 }
966
967 for_each_online_node(nid)
968 sparse_memory_present_with_active_regions(nid);
917} 969}
918 970
919void __init paging_init(void) 971void __init paging_init(void)