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

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

Merge "soc: qcom: mem-offline: Set offlinable region based on minimum DDR sizes"

parents 85743714 50ee0db3
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -16,9 +16,28 @@ 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.
- offline-sizes: Array of offlinable memory region sizes to apply to targets
	based on their DDR size.

	Each entry in the array is a pair of sizes, where the first size in the
	pair is the minimum amount of DDR required in the system in bytes, and
	the second item in the pair is the size of the offlinable region in
	bytes which will be applied to the system.

	The offlinable memory region size from the entry where the minimum amount
	of DDR required in the system is closest, but not greater, than the
	amount of DDR in the system will be applied.
	If there are no entries with a minimum amount of DDR required that is less
	than the amount of DDR in the system then no offlinable region will be
	created.

	For example, in the following configuration:
              offline-sizes = <0x1 0x40000000 0x0 0x40000000>,
			      <0x1 0xc0000000 0x0 0x80000000>;
	On a 4GB target no offlinable region will be created.
	On a 6GB target a 1GB offlinable region will be created.
	On an 8GB target a 2GB offlinable region will be created.
	On a 12GB target a 2GB offlinable region will be created.
- mboxes: Reference to the mailbox used by the driver to make requests to
	online/offline memory.

@@ -26,6 +45,7 @@ Example:
  mem-offline {
	compatible = "qcom,mem-offline";
	granule = <512>;
	mem-percent = "35";
	offline-sizes = <0x1 0x40000000 0x0 0x40000000>,
                        <0x1 0xc0000000 0x0 0x80000000>;
	mboxes = <&qmp_aop 0>;
  };
+39 −14
Original line number Diff line number Diff line
@@ -324,11 +324,13 @@ phys_addr_t bootloader_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 node;
	unsigned long long ram_sz, sz;
	phys_addr_t end_addr, addr_aligned, offset;
	int ret;
	int len;
	const __be32 *prop;
	phys_addr_t min_ddr_sz = 0, offline_sz = 0;
	int t_len = (2 * dt_root_size_cells) * sizeof(__be32);

	ram_sz = memblock_phys_mem_size();
	node = of_get_flat_dt_subnode_by_name(dt_root, "mem-offline");
@@ -336,23 +338,46 @@ static void __init update_memory_limit(void)
		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");

	prop = of_get_flat_dt_prop(node, "offline-sizes", &len);
	if (prop) {
		if (len % t_len != 0) {
			pr_err("mem-offline: invalid offline-sizes property\n");
			return;
		}

	ret = kstrtoul(p, 10, &mp);
	if (ret) {
		pr_err("mem-offine: kstrtoul failed\n");
		while (len > 0) {
			phys_addr_t tmp_min_ddr_sz = dt_mem_next_cell(
							dt_root_addr_cells,
							&prop);
			phys_addr_t tmp_offline_sz = dt_mem_next_cell(
							dt_root_size_cells,
							&prop);

			if (tmp_min_ddr_sz < ram_sz &&
			    tmp_min_ddr_sz > min_ddr_sz) {
				if (tmp_offline_sz < ram_sz) {
					min_ddr_sz = tmp_min_ddr_sz;
					offline_sz = tmp_offline_sz;
				} else {
					pr_info("mem-offline: invalid offline size:%pa\n",
						 &tmp_offline_sz);
				}
			}
			len -= t_len;
		}
	} else {
		pr_err("mem-offine: offline-sizes property not found in DT\n");
		return;
	}

	if (mp > 100) {
		pr_err("mem-offine: Invalid mem-percent DT property\n");
	if (offline_sz == 0) {
		pr_info("mem-offline: no memory to offline for DDR size:%llu\n",
			ram_sz);
		return;
	}
	sz = ram_sz - ((ram_sz * mp) / 100);

	sz = ram_sz - offline_sz;
	memory_limit = (phys_addr_t)sz;
	end_addr = memblock_max_addr(memory_limit);
	addr_aligned = ALIGN(end_addr, MIN_MEMORY_BLOCK_SIZE);
+1 −1
Original line number Diff line number Diff line
@@ -487,7 +487,7 @@ static ssize_t allocated_bytes_show(struct device *dev,
		&NODE_DATA(numa_node_id())->node_zones[ZONE_MOVABLE];
	unsigned long used, block_sz = get_memory_block_size();

	if (mem->state != MEM_ONLINE)
	if (!populated_zone(movable_zone) || mem->state != MEM_ONLINE)
		return snprintf(buf, 100, "0\n");

	block_id = base_memory_block_id(mem->start_section_nr);
+9 −3
Original line number Diff line number Diff line
@@ -188,8 +188,8 @@ static int mem_online_remaining_blocks(void)
	start_section_nr = pfn_to_section_nr(memblock_end_pfn);
	end_section_nr = pfn_to_section_nr(ram_end_pfn);

	if (start_section_nr == end_section_nr) {
		pr_err("mem-offline: System booted with no zone movable memory blocks. Cannot perform memory offlining\n");
	if (start_section_nr >= end_section_nr) {
		pr_info("mem-offline: System booted with no zone movable memory blocks. Cannot perform memory offlining\n");
		return -EINVAL;
	}
	for (memblock = start_section_nr; memblock <= end_section_nr;
@@ -361,10 +361,16 @@ static struct notifier_block hotplug_memory_callback_nb = {

static int mem_offline_driver_probe(struct platform_device *pdev)
{
	int ret;

	if (mem_parse_dt(pdev))
		return -ENODEV;

	if (mem_online_remaining_blocks())
	ret = mem_online_remaining_blocks();
	if (ret < 0)
		return -ENODEV;

	if (ret > 0)
		pr_err("mem-offline: !!ERROR!! Auto onlining some memory blocks failed. System could run with less RAM\n");

	if (mem_sysfs_init())