diff options
author | David Rientjes <rientjes@google.com> | 2007-07-21 11:10:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-21 21:37:10 -0400 |
commit | 3af044e0f832cfa3fcdce14dc30678b79dd36995 (patch) | |
tree | bd80fcea7b37c9eeef8d23b25d470b4a43c0e4ac /arch/x86_64 | |
parent | 34feb2c83beb3bdf13535a36770f7e50b47ef299 (diff) |
x86_64: extract helper function from e820_register_active_regions
The logic in e820_find_active_regions() for determining the true active
regions for an e820 entry given a range of PFN's is needed for
e820_hole_size() as well.
e820_hole_size() is called from the NUMA emulation code to determine the
reserved area within an address range on a per-node basis. Its logic should
duplicate that of finding active regions in an e820 entry because these are
the only true ranges we may register anyway.
[akpm@linux-foundation.org: cleanup]
Cc: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/e820.c | 82 |
1 files changed, 48 insertions, 34 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 13c6c37610e0..2570643ba1c5 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -289,47 +289,61 @@ void __init e820_mark_nosave_regions(void) | |||
289 | } | 289 | } |
290 | } | 290 | } |
291 | 291 | ||
292 | /* Walk the e820 map and register active regions within a node */ | 292 | /* |
293 | void __init | 293 | * Finds an active region in the address range from start_pfn to end_pfn and |
294 | e820_register_active_regions(int nid, unsigned long start_pfn, | 294 | * returns its range in ei_startpfn and ei_endpfn for the e820 entry. |
295 | unsigned long end_pfn) | 295 | */ |
296 | static int __init e820_find_active_region(const struct e820entry *ei, | ||
297 | unsigned long start_pfn, | ||
298 | unsigned long end_pfn, | ||
299 | unsigned long *ei_startpfn, | ||
300 | unsigned long *ei_endpfn) | ||
296 | { | 301 | { |
297 | int i; | 302 | *ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT; |
298 | unsigned long ei_startpfn, ei_endpfn; | 303 | *ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE) >> PAGE_SHIFT; |
299 | for (i = 0; i < e820.nr_map; i++) { | ||
300 | struct e820entry *ei = &e820.map[i]; | ||
301 | ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT; | ||
302 | ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE) | ||
303 | >> PAGE_SHIFT; | ||
304 | 304 | ||
305 | /* Skip map entries smaller than a page */ | 305 | /* Skip map entries smaller than a page */ |
306 | if (ei_startpfn >= ei_endpfn) | 306 | if (*ei_startpfn >= *ei_endpfn) |
307 | continue; | 307 | return 0; |
308 | 308 | ||
309 | /* Check if end_pfn_map should be updated */ | 309 | /* Check if end_pfn_map should be updated */ |
310 | if (ei->type != E820_RAM && ei_endpfn > end_pfn_map) | 310 | if (ei->type != E820_RAM && *ei_endpfn > end_pfn_map) |
311 | end_pfn_map = ei_endpfn; | 311 | end_pfn_map = *ei_endpfn; |
312 | 312 | ||
313 | /* Skip if map is outside the node */ | 313 | /* Skip if map is outside the node */ |
314 | if (ei->type != E820_RAM || | 314 | if (ei->type != E820_RAM || *ei_endpfn <= start_pfn || |
315 | ei_endpfn <= start_pfn || | 315 | *ei_startpfn >= end_pfn) |
316 | ei_startpfn >= end_pfn) | 316 | return 0; |
317 | continue; | ||
318 | 317 | ||
319 | /* Check for overlaps */ | 318 | /* Check for overlaps */ |
320 | if (ei_startpfn < start_pfn) | 319 | if (*ei_startpfn < start_pfn) |
321 | ei_startpfn = start_pfn; | 320 | *ei_startpfn = start_pfn; |
322 | if (ei_endpfn > end_pfn) | 321 | if (*ei_endpfn > end_pfn) |
323 | ei_endpfn = end_pfn; | 322 | *ei_endpfn = end_pfn; |
324 | 323 | ||
325 | /* Obey end_user_pfn to save on memmap */ | 324 | /* Obey end_user_pfn to save on memmap */ |
326 | if (ei_startpfn >= end_user_pfn) | 325 | if (*ei_startpfn >= end_user_pfn) |
327 | continue; | 326 | return 0; |
328 | if (ei_endpfn > end_user_pfn) | 327 | if (*ei_endpfn > end_user_pfn) |
329 | ei_endpfn = end_user_pfn; | 328 | *ei_endpfn = end_user_pfn; |
330 | 329 | ||
331 | add_active_range(nid, ei_startpfn, ei_endpfn); | 330 | return 1; |
332 | } | 331 | } |
332 | |||
333 | /* Walk the e820 map and register active regions within a node */ | ||
334 | void __init | ||
335 | e820_register_active_regions(int nid, unsigned long start_pfn, | ||
336 | unsigned long end_pfn) | ||
337 | { | ||
338 | unsigned long ei_startpfn; | ||
339 | unsigned long ei_endpfn; | ||
340 | int i; | ||
341 | |||
342 | for (i = 0; i < e820.nr_map; i++) | ||
343 | if (e820_find_active_region(&e820.map[i], | ||
344 | start_pfn, end_pfn, | ||
345 | &ei_startpfn, &ei_endpfn)) | ||
346 | add_active_range(nid, ei_startpfn, ei_endpfn); | ||
333 | } | 347 | } |
334 | 348 | ||
335 | /* | 349 | /* |