aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Tollefson <kniht@us.ibm.com>2008-10-16 14:59:43 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-21 00:17:48 -0400
commite81703724a966120ace6504c993bda9e084cbf3e (patch)
tree0b0914346bc745cab9e59b9edbe95aa764aa6959
parenta5598ca0d49821912a5053c05f07fd650671eb6d (diff)
powerpc/numa: Make memory reserve code more robust
Adjust amount to reserve based on previous nodes for reserves spanning multiple nodes. Check if the node active range is empty before attempting to pass the reserve to bootmem. In practice the range shouldn't be empty, but to be sure we check. Signed-off-by: Jon Tollefson <kniht@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/mm/numa.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 6cf5c71c431f..195bfcd08959 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -116,6 +116,7 @@ static int __init get_active_region_work_fn(unsigned long start_pfn,
116 116
117/* 117/*
118 * get_node_active_region - Return active region containing start_pfn 118 * get_node_active_region - Return active region containing start_pfn
119 * Active range returned is empty if none found.
119 * @start_pfn: The page to return the region for. 120 * @start_pfn: The page to return the region for.
120 * @node_ar: Returned set to the active region containing start_pfn 121 * @node_ar: Returned set to the active region containing start_pfn
121 */ 122 */
@@ -126,6 +127,7 @@ static void __init get_node_active_region(unsigned long start_pfn,
126 127
127 node_ar->nid = nid; 128 node_ar->nid = nid;
128 node_ar->start_pfn = start_pfn; 129 node_ar->start_pfn = start_pfn;
130 node_ar->end_pfn = start_pfn;
129 work_with_active_regions(nid, get_active_region_work_fn, node_ar); 131 work_with_active_regions(nid, get_active_region_work_fn, node_ar);
130} 132}
131 133
@@ -933,18 +935,20 @@ void __init do_init_bootmem(void)
933 struct node_active_region node_ar; 935 struct node_active_region node_ar;
934 936
935 get_node_active_region(start_pfn, &node_ar); 937 get_node_active_region(start_pfn, &node_ar);
936 while (start_pfn < end_pfn) { 938 while (start_pfn < end_pfn &&
939 node_ar.start_pfn < node_ar.end_pfn) {
940 unsigned long reserve_size = size;
937 /* 941 /*
938 * if reserved region extends past active region 942 * if reserved region extends past active region
939 * then trim size to active region 943 * then trim size to active region
940 */ 944 */
941 if (end_pfn > node_ar.end_pfn) 945 if (end_pfn > node_ar.end_pfn)
942 size = (node_ar.end_pfn << PAGE_SHIFT) 946 reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
943 - (start_pfn << PAGE_SHIFT); 947 - (start_pfn << PAGE_SHIFT);
944 dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, size, 948 dbg("reserve_bootmem %lx %lx nid=%d\n", physbase,
945 node_ar.nid); 949 reserve_size, node_ar.nid);
946 reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase, 950 reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
947 size, BOOTMEM_DEFAULT); 951 reserve_size, BOOTMEM_DEFAULT);
948 /* 952 /*
949 * if reserved region is contained in the active region 953 * if reserved region is contained in the active region
950 * then done. 954 * then done.
@@ -959,6 +963,7 @@ void __init do_init_bootmem(void)
959 */ 963 */
960 start_pfn = node_ar.end_pfn; 964 start_pfn = node_ar.end_pfn;
961 physbase = start_pfn << PAGE_SHIFT; 965 physbase = start_pfn << PAGE_SHIFT;
966 size = size - reserve_size;
962 get_node_active_region(start_pfn, &node_ar); 967 get_node_active_region(start_pfn, &node_ar);
963 } 968 }
964 969