aboutsummaryrefslogtreecommitdiffstats
path: root/mm
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 /mm
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>
Diffstat (limited to 'mm')
-rw-r--r--mm/page_alloc.c22
1 files changed, 19 insertions, 3 deletions
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 */