aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorMatt Redfearn <[email protected]>2016-03-31 10:05:38 +0100
committerRalf Baechle <[email protected]>2016-05-13 14:02:03 +0200
commit61cd52d4e44d7d8c55dad939b1877fd39d7103a2 (patch)
tree011f726da8bb6b807385d185c51ae9ff9331ab87 /arch/mips/kernel
parentaf09ab5e3fa7b6e137b135325a2ca00d57b4aea2 (diff)
MIPS: bootmem: When relocatable, free memory below kernel
The kernel reserves all memory before the _end symbol as bootmem, however, once the kernel can be relocated elsewhere in memory this may result in a large amount of wasted memory. The assumption is that the memory between the link and relocated address of the kernel may be released back to the available memory pool. Memory statistics for a Malta with the kernel relocating by 16Mb, without the patch: Memory: 105952K/131072K available (4604K kernel code, 242K rwdata, 892K rodata, 1280K init, 183K bss, 25120K reserved, 0K cma-reserved) And with the patch: Memory: 122336K/131072K available (4604K kernel code, 242K rwdata, 892K rodata, 1280K init, 183K bss, 8736K reserved, 0K cma-reserved) The 16Mb offset is removed from the reserved region and added back to the available region. Signed-off-by: Matt Redfearn <[email protected]> Cc: Aaro Koskinen <[email protected]> Cc: Masahiro Yamada <[email protected]> Cc: Alexander Sverdlin <[email protected]> Cc: Jaedon Shin <[email protected]> Cc: James Hogan <[email protected]> Cc: Jonas Gorski <[email protected]> Cc: Paul Burton <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Patchwork: https://patchwork.linux-mips.org/patch/12986/ Signed-off-by: Ralf Baechle <[email protected]>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/setup.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index d20caacfdbd3..3378fdaf4dd3 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -469,6 +469,20 @@ static void __init bootmem_init(void)
*/
reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT);
+#ifdef CONFIG_RELOCATABLE
+ /*
+ * The kernel reserves all memory below its _end symbol as bootmem,
+ * but the kernel may now be at a much higher address. The memory
+ * between the original and new locations may be returned to the system.
+ */
+ if (__pa_symbol(_text) > __pa_symbol(VMLINUX_LOAD_ADDRESS)) {
+ unsigned long offset;
+
+ offset = __pa_symbol(_text) - __pa_symbol(VMLINUX_LOAD_ADDRESS);
+ free_bootmem(__pa_symbol(VMLINUX_LOAD_ADDRESS), offset);
+ }
+#endif
+
/*
* Reserve initrd memory if needed.
*/