Commit f9a7febd authored by Greg Ungerer's avatar Greg Ungerer Committed by Ralf Baechle

MIPS: Fix start of free memory when using initrd

Currently when using an initrd on a MIPS system the start of the bootmem
region of memory is set to the larger of the end of the kernel bss region
(_end) or the end of the initrd. In a typical memory layout where the
initrd is at some address above the kernel image this means that the start
of the bootmem region will be the end of the initrd. But when we are done
processing/loading the initrd we have no way to reclaim the memory region
it occupied, and we lose a large chunk of now otherwise empty RAM from our
final running system.

The bootmem code is designed to allow this initrd to be reserved (and the
code in finalize_initrd() currently does this). When the initrd is finally
processed/loaded its reserved memory is freed.

Fix the setting of the start of the bootmem map to be the end of the kernel.

[ralf@linux-mips.org: fold in the fix of Ashok Kumar <ashoks@broadcom.com>.]
Signed-off-by: default avatarGreg Ungerer <gerg@uclinux.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/1574/
Cc: Ashok Kumar <ashoks@broadcom.com>
Patchwork: https://patchwork.linux-mips.org/patch/5883/
Patchwork: https://patchwork.linux-mips.org/patch/6028/
Patchwork: https://patchwork.linux-mips.org/patch/6064/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 007fbbea
...@@ -300,12 +300,13 @@ static void __init bootmem_init(void) ...@@ -300,12 +300,13 @@ static void __init bootmem_init(void)
int i; int i;
/* /*
* Init any data related to initrd. It's a nop if INITRD is * Sanity check any INITRD first. We don't take it into account
* not selected. Once that done we can determine the low bound * for bootmem setup initially, rely on the end-of-kernel-code
* of usable memory. * as our memory range starting point. Once bootmem is inited we
* will reserve the area used for the initrd.
*/ */
reserved_end = max(init_initrd(), init_initrd();
(unsigned long) PFN_UP(__pa_symbol(&_end))); reserved_end = (unsigned long) PFN_UP(__pa_symbol(&_end));
/* /*
* max_low_pfn is not a number of pages. The number of pages * max_low_pfn is not a number of pages. The number of pages
...@@ -362,6 +363,14 @@ static void __init bootmem_init(void) ...@@ -362,6 +363,14 @@ static void __init bootmem_init(void)
max_low_pfn = PFN_DOWN(HIGHMEM_START); max_low_pfn = PFN_DOWN(HIGHMEM_START);
} }
#ifdef CONFIG_BLK_DEV_INITRD
/*
* mapstart should be after initrd_end
*/
if (initrd_end)
mapstart = max(mapstart, (unsigned long)PFN_UP(__pa(initrd_end)));
#endif
/* /*
* Initialize the boot-time allocator with low memory only. * Initialize the boot-time allocator with low memory only.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment