diff options
| -rw-r--r-- | arch/x86/kernel/e820.c | 3 | ||||
| -rw-r--r-- | include/linux/memblock.h | 1 | ||||
| -rw-r--r-- | mm/memblock.c | 24 |
3 files changed, 28 insertions, 0 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index ed858e9e9a74..df06ade26bef 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
| @@ -1077,6 +1077,9 @@ void __init memblock_x86_fill(void) | |||
| 1077 | memblock_add(ei->addr, ei->size); | 1077 | memblock_add(ei->addr, ei->size); |
| 1078 | } | 1078 | } |
| 1079 | 1079 | ||
| 1080 | /* throw away partial pages */ | ||
| 1081 | memblock_trim_memory(PAGE_SIZE); | ||
| 1082 | |||
| 1080 | memblock_dump_all(); | 1083 | memblock_dump_all(); |
| 1081 | } | 1084 | } |
| 1082 | 1085 | ||
diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 569d67d4243e..d452ee191066 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h | |||
| @@ -57,6 +57,7 @@ int memblock_add(phys_addr_t base, phys_addr_t size); | |||
| 57 | int memblock_remove(phys_addr_t base, phys_addr_t size); | 57 | int memblock_remove(phys_addr_t base, phys_addr_t size); |
| 58 | int memblock_free(phys_addr_t base, phys_addr_t size); | 58 | int memblock_free(phys_addr_t base, phys_addr_t size); |
| 59 | int memblock_reserve(phys_addr_t base, phys_addr_t size); | 59 | int memblock_reserve(phys_addr_t base, phys_addr_t size); |
| 60 | void memblock_trim_memory(phys_addr_t align); | ||
| 60 | 61 | ||
| 61 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP | 62 | #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP |
| 62 | void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, | 63 | void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, |
diff --git a/mm/memblock.c b/mm/memblock.c index 931eef145af5..625905523c2a 100644 --- a/mm/memblock.c +++ b/mm/memblock.c | |||
| @@ -930,6 +930,30 @@ int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t si | |||
| 930 | return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; | 930 | return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; |
| 931 | } | 931 | } |
| 932 | 932 | ||
| 933 | void __init_memblock memblock_trim_memory(phys_addr_t align) | ||
| 934 | { | ||
| 935 | int i; | ||
| 936 | phys_addr_t start, end, orig_start, orig_end; | ||
| 937 | struct memblock_type *mem = &memblock.memory; | ||
| 938 | |||
| 939 | for (i = 0; i < mem->cnt; i++) { | ||
| 940 | orig_start = mem->regions[i].base; | ||
| 941 | orig_end = mem->regions[i].base + mem->regions[i].size; | ||
| 942 | start = round_up(orig_start, align); | ||
| 943 | end = round_down(orig_end, align); | ||
| 944 | |||
| 945 | if (start == orig_start && end == orig_end) | ||
| 946 | continue; | ||
| 947 | |||
| 948 | if (start < end) { | ||
| 949 | mem->regions[i].base = start; | ||
| 950 | mem->regions[i].size = end - start; | ||
| 951 | } else { | ||
| 952 | memblock_remove_region(mem, i); | ||
| 953 | i--; | ||
| 954 | } | ||
| 955 | } | ||
| 956 | } | ||
| 933 | 957 | ||
| 934 | void __init_memblock memblock_set_current_limit(phys_addr_t limit) | 958 | void __init_memblock memblock_set_current_limit(phys_addr_t limit) |
| 935 | { | 959 | { |
