ANDROID: memblock: introduce an early param for memsize
So far there was only debugfs interface to see the memsize results. As
debugfs is not allowed on the production binary, procfs would be
preferred than debugfs. To work as same as possible like the upstream,
provide an option to disable memsize.
With this change, memsize will be disabled by default, and memsize would
be enabled as procfs or debugfs through the option in the cmdline.
i.e.
memblock_memsize=none (default)
memblock_memsize=procfs
memblock_memsize=debugfs
For your information, let me explain more about this memsize solution.
Some of memory regions can be reserved for a specific purpose. They are
usually defined through reserved-memory in device tree. If only size
without address is specified in device tree, the address of the region
will be determined at boot time.
We may find the address of the memory regions through booting log, but
it does not show all. And it could be hard to catch the very beginning
log. The memblock_dump_all shows all memblock status but it does not
show region name and its information is difficult to summarize.
1. How to use
The memsize solution shows reserved memory status and boot time kernel
memory size.
To enable and see it, add one of this on the cmdline.
memblock_memsize=procfs
memblock_memsize=debugfs
To see the address, do the following command.
echo 1 > /proc/sys/kernel/kptr_restrict
To see the results, do the following command.
cat /proc/memsize or cat /DEBUGFS/memblock/memsize
2. How it works
This is how the main internal logic works. The kernel size will be
tracked by adding hooking code into memblock_[add_range|remove_range],
and other reserved regions will be recored by calling
memblock_memsize_record.
A. tracking kernel size
During the boot, memblock allocation and free are tracked by every call
of memblock_[add_range|remove_range]. The total size will be saved
at the memsize_kinit variable.
B. tracking non kernel size
The reserved memory regions defined in device tree and
some special regions are recorded by calling memblock_memsize_record.
B.1. reserved region in the device tree and elfcorehdr
early_init_fdt_scan_reserved_mem
memblock_memsize_detect_hole [memsize]
memblock_memsize_record [memsize]
memblock_memsize_disable_tracking [memsize]
fdt_scan_reserved_mem
fdt_reserve_elfcorehdr
memblock_memsize_record [memsize]
memblock_memsize_record for memreserve [memsize]
fdt_init_reserved_mem
memblock_memsize_record [memsize]
memblock_memsize_enable_tracking [memsize]
B2. add the default cma region
dma_contiguous_reserve_area
memblock_memsize_record [memsize]
C. userspace interface
The recorded information can be shown by userspace interface.
procfs/debugfs
memblock_memsize_show [memsize]
memblock_memsize_check_size [memsize]
memblock_memsize_free [memsize]
memblock_memsize_record [memsize]
Bug: 340432773
Signed-off-by: Jaewon Kim <jaewon31.kim@samsung.com>
Change-Id: Ideefb9de0cbb9ebc91af7d3c79abf3571db27481
This commit is contained in:
committed by
Suren Baghdasaryan
parent
99b134ba86
commit
eab69cfe9c
+34
-2
@@ -20,6 +20,7 @@
|
||||
#include <asm/sections.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -2086,6 +2087,30 @@ static unsigned long memsize_ro __initdata_memblock;
|
||||
static unsigned long memsize_bss __initdata_memblock;
|
||||
static long memsize_reusable_size;
|
||||
|
||||
enum memblock_memsize_state {
|
||||
MEMBLOCK_MEMSIZE_NONE = 0,
|
||||
MEMBLOCK_MEMSIZE_DEBUGFS,
|
||||
MEMBLOCK_MEMSIZE_PROCFS,
|
||||
};
|
||||
|
||||
static enum memblock_memsize_state memsize_state __initdata_memblock = MEMBLOCK_MEMSIZE_NONE;
|
||||
|
||||
static int __init early_memblock_memsize(char *str)
|
||||
{
|
||||
if (!str)
|
||||
return -EINVAL;
|
||||
if (strcmp(str, "none") == 0)
|
||||
memsize_state = MEMBLOCK_MEMSIZE_NONE;
|
||||
else if (strcmp(str, "debugfs") == 0)
|
||||
memsize_state = MEMBLOCK_MEMSIZE_DEBUGFS;
|
||||
else if (strcmp(str, "procfs") == 0)
|
||||
memsize_state = MEMBLOCK_MEMSIZE_PROCFS;
|
||||
else
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
early_param("memblock_memsize", early_memblock_memsize);
|
||||
|
||||
void __init memblock_memsize_enable_tracking(void)
|
||||
{
|
||||
memblock_memsize_tracking = true;
|
||||
@@ -2246,6 +2271,9 @@ void __init_memblock memblock_memsize_record(const char *name, phys_addr_t base,
|
||||
struct memsize_rgn_struct *rgn;
|
||||
phys_addr_t end;
|
||||
|
||||
if (name && memsize_state == MEMBLOCK_MEMSIZE_NONE)
|
||||
return;
|
||||
|
||||
if (memsize_rgn_count == CONFIG_MAX_MEMBLOCK_MEMSIZE) {
|
||||
pr_err("not enough space on memsize_rgn\n");
|
||||
return;
|
||||
@@ -2882,8 +2910,12 @@ static int __init memblock_init_debugfs(void)
|
||||
&memblock_debug_fops);
|
||||
#endif
|
||||
#ifdef CONFIG_MEMBLOCK_MEMSIZE
|
||||
debugfs_create_file("memsize", 0444, root,
|
||||
NULL, &memblock_memsize_fops);
|
||||
if (memsize_state == MEMBLOCK_MEMSIZE_DEBUGFS)
|
||||
debugfs_create_file("memsize", 0444, root, NULL,
|
||||
&memblock_memsize_fops);
|
||||
else if (memsize_state == MEMBLOCK_MEMSIZE_PROCFS)
|
||||
proc_create_single("memsize", 0, NULL,
|
||||
memblock_memsize_show);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user