Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42be9559 authored by Sudarshan Rajagopalan's avatar Sudarshan Rajagopalan Committed by Isaac J. Manjarres
Browse files

arm64: mm/memblock: Update memory limit calculation



The system RAM region would not be ideally contiguous from
start to end of DRAM. Detect any offset/holes present in the
DDR region and update the memory limit being set, so that the
DRAM end address is aligned to the memory block size. This is
a requirement for mem-offline framework to work properly.

Change-Id: I97cb0cce70e7c414ae2d200a4a3f714d145c0e64
Signed-off-by: default avatarSudarshan Rajagopalan <sudaraja@codeaurora.org>
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent d05df014
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <linux/crash_dump.h>
#include <linux/memory.h>
#include <linux/libfdt.h>
#include <linux/memblock.h>

#include <asm/boot.h>
#include <asm/fixmap.h>
@@ -268,9 +269,10 @@ static void __init update_memory_limit(void)
	unsigned long node, mp;
	const char *p;
	unsigned long long ram_sz, sz;
	phys_addr_t end_addr, addr_aligned, offset;
	int ret;

	ram_sz = memblock_end_of_DRAM() - memblock_start_of_DRAM();
	ram_sz = memblock_phys_mem_size();
	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");
@@ -294,7 +296,17 @@ static void __init update_memory_limit(void)
	}
	sz = ram_sz - ((ram_sz * mp) / 100);
	memory_limit = (phys_addr_t)sz;
	memory_limit = ALIGN(memory_limit, MIN_MEMORY_BLOCK_SIZE);
	end_addr = memblock_max_addr(memory_limit);
	addr_aligned = ALIGN(end_addr, MIN_MEMORY_BLOCK_SIZE);
	offset = addr_aligned - end_addr;

	if (offset > MIN_MEMORY_BLOCK_SIZE / 2) {
		addr_aligned = ALIGN_DOWN(end_addr, MIN_MEMORY_BLOCK_SIZE);
		offset = end_addr - addr_aligned;
		memory_limit -= offset;
	} else {
		memory_limit += offset;
	}

	pr_notice("Memory limit set/overridden to %lldMB\n",
							memory_limit >> 20);
+1 −0
Original line number Diff line number Diff line
@@ -441,6 +441,7 @@ phys_addr_t memblock_reserved_size(void);
phys_addr_t memblock_mem_size(unsigned long limit_pfn);
phys_addr_t memblock_start_of_DRAM(void);
phys_addr_t memblock_end_of_DRAM(void);
phys_addr_t memblock_max_addr(phys_addr_t limit);
void memblock_enforce_memory_limit(phys_addr_t memory_limit);
void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
void memblock_mem_limit_remove_map(phys_addr_t limit);
+5 −0
Original line number Diff line number Diff line
@@ -1645,6 +1645,11 @@ static phys_addr_t __init_memblock __find_max_addr(phys_addr_t limit)
	return max_addr;
}

phys_addr_t __init_memblock memblock_max_addr(phys_addr_t limit)
{
	return __find_max_addr(limit);
}

void __init memblock_enforce_memory_limit(phys_addr_t limit)
{
	phys_addr_t max_addr = PHYS_ADDR_MAX;