Skip to content

Commit 4055531

Browse files
Yinghai Lugregkh
Yinghai Lu
authored andcommitted
x86, mm: Trim memory in memblock to be page aligned
commit 6ede1fd upstream. We will not map partial pages, so need to make sure memblock allocation will not allocate those bytes out. Also we will use for_each_mem_pfn_range() to loop to map memory range to keep them consistent. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Link: http://lkml.kernel.org/r/CAE9FiQVZirvaBMFYRfXMmWEcHbKSicQEHz4VAwUv0xFCk51ZNw@mail.gmail.com Acked-by: Jacob Shin <jacob.shin@amd.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8a9ff86 commit 4055531

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

arch/x86/kernel/e820.c

+3
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,9 @@ void __init memblock_x86_fill(void)
10771077
memblock_add(ei->addr, ei->size);
10781078
}
10791079

1080+
/* throw away partial pages */
1081+
memblock_trim_memory(PAGE_SIZE);
1082+
10801083
memblock_dump_all();
10811084
}
10821085

include/linux/memblock.h

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ int memblock_add(phys_addr_t base, phys_addr_t size);
5757
int memblock_remove(phys_addr_t base, phys_addr_t size);
5858
int memblock_free(phys_addr_t base, phys_addr_t size);
5959
int memblock_reserve(phys_addr_t base, phys_addr_t size);
60+
void memblock_trim_memory(phys_addr_t align);
6061

6162
#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
6263
void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn,

mm/memblock.c

+24
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,30 @@ int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t si
929929
return memblock_overlaps_region(&memblock.reserved, base, size) >= 0;
930930
}
931931

932+
void __init_memblock memblock_trim_memory(phys_addr_t align)
933+
{
934+
int i;
935+
phys_addr_t start, end, orig_start, orig_end;
936+
struct memblock_type *mem = &memblock.memory;
937+
938+
for (i = 0; i < mem->cnt; i++) {
939+
orig_start = mem->regions[i].base;
940+
orig_end = mem->regions[i].base + mem->regions[i].size;
941+
start = round_up(orig_start, align);
942+
end = round_down(orig_end, align);
943+
944+
if (start == orig_start && end == orig_end)
945+
continue;
946+
947+
if (start < end) {
948+
mem->regions[i].base = start;
949+
mem->regions[i].size = end - start;
950+
} else {
951+
memblock_remove_region(mem, i);
952+
i--;
953+
}
954+
}
955+
}
932956

933957
void __init_memblock memblock_set_current_limit(phys_addr_t limit)
934958
{

0 commit comments

Comments
 (0)