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

Commit bcd47c41 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: mem-offline: Add support for QMP mailbox communication"

parents 7ef8c71c 49cd0014
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
Memory offline driver
=====================

The memory offline driver supports the onlining and offlining of DDR memory.
Through the mem-offline node you can configure how much of the DDR will
support being offlined/onlined.
By default all memory is onlined when the device has booted up.

Note that offlinable memory can only support 'movable' memory allocations so
designating too much memory as offlinable can result in system performance and
stability issues.

For more information on how to request the onlining and offlining of memory
see the memory hotplug documentation (Documentation/memory-hotplug.txt).

Required properties:
- compatible: "qcom,mem-offline"
- granule: The minimum granule size in mega-bytes for memory onlining/offlining.
- mem-percent: Percentage of the DDR which will support being onlined/offlined.
	The system will round down the value to align with the minimum offlinable
	granule size supported by DDR.
- mboxes: Reference to the mailbox used by the driver to make requests to
	online/offline memory.

Example:
  mem-offline {
	compatible = "qcom,mem-offline";
	granule = <512>;
	mem-percent = "35";
	mboxes = <&qmp_aop 0>;
  };
+12 −0
Original line number Diff line number Diff line
@@ -262,6 +262,18 @@ config HAVE_GENERIC_GUP
config SMP
	def_bool y

config HOTPLUG_SIZE_BITS
	int "Memory hotplug block size(29 => 512MB 30 => 1GB)"
	depends on SPARSEMEM
	depends on MEMORY_HOTPLUG
	depends on QCOM_MEM_OFFLINE
	default 30
	help
	 Selects granularity of hotplug memory. Block
	 size for memory hotplug is represent as a power
	 of 2.
	 If unsure, stick with default value.

config KERNEL_MODE_NEON
	def_bool y

+4 −0
Original line number Diff line number Diff line
@@ -18,7 +18,11 @@

#ifdef CONFIG_SPARSEMEM
#define MAX_PHYSMEM_BITS	CONFIG_ARM64_PA_BITS
#ifndef CONFIG_MEMORY_HOTPLUG
#define SECTION_SIZE_BITS	30
#else
#define SECTION_SIZE_BITS	CONFIG_HOTPLUG_SIZE_BITS
#endif
#endif

#endif
+48 −0
Original line number Diff line number Diff line
@@ -40,6 +40,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>
@@ -317,6 +319,51 @@ static void __init arm64_memory_present(void)
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.
 */
@@ -401,6 +448,7 @@ void __init arm64_memblock_init(void)
		memblock_remove(0, memstart_addr);
	}

	update_memory_limit();
	/*
	 * Save bootloader imposed memory limit before we overwirte
	 * memblock.
+3 −1
Original line number Diff line number Diff line
@@ -708,11 +708,13 @@ void hotplug_paging(phys_addr_t start, phys_addr_t size)
	struct page *pg;
	phys_addr_t pgd_phys = pgd_pgtable_alloc();
	pgd_t *pgd = pgd_set_fixmap(pgd_phys);
	int flags;

	memcpy(pgd, swapper_pg_dir, PAGE_SIZE);
	flags = debug_pagealloc_enabled() ? NO_BLOCK_MAPPINGS : 0;

	__create_pgd_mapping(pgd, start, __phys_to_virt(start), size,
		PAGE_KERNEL, pgd_pgtable_alloc, !debug_pagealloc_enabled());
		PAGE_KERNEL, pgd_pgtable_alloc, flags);

	cpu_replace_ttbr1(__va(pgd_phys));
	memcpy(swapper_pg_dir, pgd, PAGE_SIZE);
Loading