diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-10-27 14:45:49 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-10-28 08:54:44 -0400 |
commit | df4f14c7b22e43e67c0e4e3b005ff897a0a72f4d (patch) | |
tree | 1e4bc4f02854bb7e6559301fd79031747ba3c2b0 /arch/arm/mm | |
parent | d0e775afb94d9b61ba6c63299169ef7a87b68189 (diff) |
ARM: memblock: convert free_highpages() to use memblock
Free the high pages using the memblock memory lists - and more
importantly, exclude any memblock allocations in highmem from the
free'd memory.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/init.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 1b4e0abf113a..5422821d372f 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -439,13 +439,47 @@ static void __init free_unused_memmap(struct meminfo *mi) | |||
439 | static void __init free_highpages(void) | 439 | static void __init free_highpages(void) |
440 | { | 440 | { |
441 | #ifdef CONFIG_HIGHMEM | 441 | #ifdef CONFIG_HIGHMEM |
442 | int i; | 442 | unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET; |
443 | struct memblock_region *mem, *res; | ||
443 | 444 | ||
444 | /* set highmem page free */ | 445 | /* set highmem page free */ |
445 | for_each_bank (i, &meminfo) { | 446 | for_each_memblock(memory, mem) { |
446 | unsigned long start = bank_pfn_start(&meminfo.bank[i]); | 447 | unsigned long start = memblock_region_memory_base_pfn(mem); |
447 | unsigned long end = bank_pfn_end(&meminfo.bank[i]); | 448 | unsigned long end = memblock_region_memory_end_pfn(mem); |
448 | if (start >= max_low_pfn + PHYS_PFN_OFFSET) | 449 | |
450 | /* Ignore complete lowmem entries */ | ||
451 | if (end <= max_low) | ||
452 | continue; | ||
453 | |||
454 | /* Truncate partial highmem entries */ | ||
455 | if (start < max_low) | ||
456 | start = max_low; | ||
457 | |||
458 | /* Find and exclude any reserved regions */ | ||
459 | for_each_memblock(reserved, res) { | ||
460 | unsigned long res_start, res_end; | ||
461 | |||
462 | res_start = memblock_region_reserved_base_pfn(res); | ||
463 | res_end = memblock_region_reserved_end_pfn(res); | ||
464 | |||
465 | if (res_end < start) | ||
466 | continue; | ||
467 | if (res_start < start) | ||
468 | res_start = start; | ||
469 | if (res_start > end) | ||
470 | res_start = end; | ||
471 | if (res_end > end) | ||
472 | res_end = end; | ||
473 | if (res_start != start) | ||
474 | totalhigh_pages += free_area(start, res_start, | ||
475 | NULL); | ||
476 | start = res_end; | ||
477 | if (start == end) | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | /* And now free anything which remains */ | ||
482 | if (start < end) | ||
449 | totalhigh_pages += free_area(start, end, NULL); | 483 | totalhigh_pages += free_area(start, end, NULL); |
450 | } | 484 | } |
451 | totalram_pages += totalhigh_pages; | 485 | totalram_pages += totalhigh_pages; |