arm64: Override memory limit set by boot parameter

To guarantee successful hot-plugging of memory blocks, these blocks
should belong to ZONE_MOVABLE which has migratable pages. Linux kernel
during boot initializes all the available memory blocks to ZONE_DMA and
ZONE_NORMAL. Hence, boot the system with less memory whose percentage
is given by mem-offline DT property 'mem-percent' and override any memory
limit imposed by kernel boot params and let mem-offline driver initialize
the remaining with ZONE_MOVABLE. The memory blocks in this zone are
applicable for memory offlining.

Change-Id: Ia7b804522fe9425101ee83d1ee354ed09483df13
Signed-off-by: Sudarshan Rajagopalan <sudaraja@codeaurora.org>
[swatsrid@codeaurora.org: Fix merge conflicts]
Signed-off-by: Swathi Sridhar <swatsrid@codeaurora.org>
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
This commit is contained in:
Sudarshan Rajagopalan 2018-04-27 14:41:03 -07:00 committed by Isaac J. Manjarres
parent 9c6628f059
commit e39b3da82e
2 changed files with 58 additions and 0 deletions

View File

@ -28,6 +28,8 @@
#include <linux/mm.h>
#include <linux/kexec.h>
#include <linux/crash_dump.h>
#include <linux/memory.h>
#include <linux/libfdt.h>
#include <asm/boot.h>
#include <asm/fixmap.h>
@ -259,6 +261,51 @@ EXPORT_SYMBOL(pfn_valid);
static phys_addr_t memory_limit = PHYS_ADDR_MAX;
phys_addr_t bootloader_memory_limit;
#ifdef CONFIG_OVERRIDE_MEMORY_LIMIT
static void __init update_memory_limit(void)
{
unsigned long dt_root = of_get_flat_dt_root();
unsigned long node, mp;
const char *p;
unsigned long long ram_sz, sz;
int ret;
ram_sz = memblock_end_of_DRAM() - memblock_start_of_DRAM();
node = of_get_flat_dt_subnode_by_name(dt_root, "mem-offline");
if (node == -FDT_ERR_NOTFOUND) {
pr_err("mem-offine node not found in FDT\n");
return;
}
p = of_get_flat_dt_prop(node, "mem-percent", NULL);
if (!p) {
pr_err("mem-offine: mem-percent property not found in FDT\n");
return;
}
ret = kstrtoul(p, 10, &mp);
if (ret) {
pr_err("mem-offine: kstrtoul failed\n");
return;
}
if (mp > 100) {
pr_err("mem-offine: Invalid mem-percent DT property\n");
return;
}
sz = ram_sz - ((ram_sz * mp) / 100);
memory_limit = (phys_addr_t)sz;
memory_limit = ALIGN(memory_limit, MIN_MEMORY_BLOCK_SIZE);
pr_notice("Memory limit set/overridden to %lldMB\n",
memory_limit >> 20);
}
#else
static void __init update_memory_limit(void)
{
}
#endif
/*
* Limit the memory size that was specified via FDT.
*/
@ -350,6 +397,7 @@ void __init arm64_memblock_init(void)
memblock_remove(0, memstart_addr);
}
update_memory_limit();
/*
* Save bootloader imposed memory limit before we overwirte
* memblock.

View File

@ -66,6 +66,16 @@ config QCOM_GENI_SE
driver is also used to manage the common aspects of multiple Serial
Engines present in the QUP.
config OVERRIDE_MEMORY_LIMIT
bool "Override memory limit set by the kernel boot parameter"
depends on QCOM_MEM_OFFLINE
help
Override any memory limit set by the kernel boot parameter with
limit set by mem-offline dt entry so that memory offline framework
can initialize remaining memory with movable pages for memory
hot-plugging.
If unsure, say N
config QCOM_GLINK_SSR
tristate "Qualcomm Glink SSR driver"
depends on RPMSG