aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMel Gorman <mel@skynet.ie>2006-09-27 04:49:58 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-27 11:26:11 -0400
commit9c7cd6877cf8db15269163deda69392263124c1e (patch)
treeff5197bdd2d5f02a5032c050eb39349534a4b14b
parent0e0b864e069c52a7b3e4a7da56e29b03a012fd75 (diff)
[PATCH] Account for holes that are outside the range of physical memory
absent_pages_in_range() made the assumption that users of the API would not care about holes beyound the end of physical memory. This was not the case. This patch will account for ranges outside of physical memory as holes correctly. 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>
-rw-r--r--arch/x86_64/mm/srat.c4
-rw-r--r--mm/page_alloc.c22
2 files changed, 22 insertions, 4 deletions
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 7b50bb1caabe..db1b2e11cf8f 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -227,7 +227,9 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end)
227 227
228 /* This check might be a bit too strict, but I'm keeping it for now. */ 228 /* This check might be a bit too strict, but I'm keeping it for now. */
229 if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) { 229 if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) {
230 printk(KERN_ERR "SRAT: Hotplug area has existing memory\n"); 230 printk(KERN_ERR
231 "SRAT: Hotplug area %lu -> %lu has existing memory\n",
232 s_pfn, e_pfn);
231 return -1; 233 return -1;
232 } 234 }
233 235
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8d9a1eb9fbba..75133e1dc4b1 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2168,6 +2168,10 @@ unsigned long __init __absent_pages_in_range(int nid,
2168 if (i == -1) 2168 if (i == -1)
2169 return 0; 2169 return 0;
2170 2170
2171 /* Account for ranges before physical memory on this node */
2172 if (early_node_map[i].start_pfn > range_start_pfn)
2173 hole_pages = early_node_map[i].start_pfn - range_start_pfn;
2174
2171 prev_end_pfn = early_node_map[i].start_pfn; 2175 prev_end_pfn = early_node_map[i].start_pfn;
2172 2176
2173 /* Find all holes for the zone within the node */ 2177 /* Find all holes for the zone within the node */
@@ -2189,6 +2193,11 @@ unsigned long __init __absent_pages_in_range(int nid,
2189 prev_end_pfn = early_node_map[i].end_pfn; 2193 prev_end_pfn = early_node_map[i].end_pfn;
2190 } 2194 }
2191 2195
2196 /* Account for ranges past physical memory on this node */
2197 if (range_end_pfn > prev_end_pfn)
2198 hole_pages = range_end_pfn -
2199 max(range_start_pfn, prev_end_pfn);
2200
2192 return hole_pages; 2201 return hole_pages;
2193} 2202}
2194 2203
@@ -2210,9 +2219,16 @@ unsigned long __init zone_absent_pages_in_node(int nid,
2210 unsigned long zone_type, 2219 unsigned long zone_type,
2211 unsigned long *ignored) 2220 unsigned long *ignored)
2212{ 2221{
2213 return __absent_pages_in_range(nid, 2222 unsigned long node_start_pfn, node_end_pfn;
2214 arch_zone_lowest_possible_pfn[zone_type], 2223 unsigned long zone_start_pfn, zone_end_pfn;
2215 arch_zone_highest_possible_pfn[zone_type]); 2224
2225 get_pfn_range_for_nid(nid, &node_start_pfn, &node_end_pfn);
2226 zone_start_pfn = max(arch_zone_lowest_possible_pfn[zone_type],
2227 node_start_pfn);
2228 zone_end_pfn = min(arch_zone_highest_possible_pfn[zone_type],
2229 node_end_pfn);
2230
2231 return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn);
2216} 2232}
2217 2233
2218/* Return the zone index a PFN is in */ 2234/* Return the zone index a PFN is in */