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 | |
| 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>
| -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; |
