[RESEND PATCH 09/10] memblock: print kernel internal size

From: Jaewon Kim
Date: Mon May 20 2024 - 22:42:12 EST


Kernel internal size information is also useful to compare with other
binary. This patch print kernel text, rwdata, rodata, bss, and others.

Here's an example.

Reserved : 1181708 KB
.kernel : 296172 KB
.text : 16960 KB
.rwdata : 2299 KB
.rodata : 16464 KB
.bss : 7549 KB
.memmap : 196608 KB
.etc : 56293 KB
.unusable : 885536 KB

Signed-off-by: Jaewon Kim <jaewon31.kim@xxxxxxxxxxx>
---
include/linux/memblock.h | 6 ++++++
mm/memblock.c | 36 ++++++++++++++++++++++++++++++++++++
mm/mm_init.c | 6 +++++-
3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index a83ad98ac252..7ab8b59bfbc1 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -623,6 +623,9 @@ extern void memblock_memsize_unset_name(void);
extern void memblock_memsize_enable_tracking(void);
extern void memblock_memsize_disable_tracking(void);
extern void memblock_memsize_mod_kernel_size(long size);
+extern void memblock_memsize_mod_memmap_size(long size);
+extern void memblock_memsize_kernel_code_data(unsigned long code,
+ unsigned long data, unsigned long ro, unsigned long bss);
#else
static inline void memblock_memsize_record(const char *name, phys_addr_t base,
phys_addr_t size, bool nomap,
@@ -633,6 +636,9 @@ static inline void memblock_memsize_unset_name(void) { }
static inline void memblock_memsize_enable_tracking(void){ }
static inline void memblock_memsize_disable_tracking(void){ }
static inline void memblock_memsize_mod_kernel_size(long size) { }
+static inline void memblock_memsize_mod_memmap_size(long size) { }
+static inline void memblock_memsize_kernel_code_data(unsigned long code,
+ unsigned long data, unsigned long ro, unsigned long bss) { }
#endif

#endif /* _LINUX_MEMBLOCK_H */
diff --git a/mm/memblock.c b/mm/memblock.c
index 0906d81f66c2..2fe0dc2575c5 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -2061,6 +2061,11 @@ static struct memsize_rgn_struct memsize_rgn[CONFIG_MAX_MEMBLOCK_MEMSIZE] __init
static int memsize_rgn_count __initdata_memblock;
static const char *memblock_memsize_name __initdata_memblock;
static long memsize_kinit __initdata_memblock;
+static long memsize_memap __initdata_memblock;
+static unsigned long memsize_code __initdata_memblock;
+static unsigned long memsize_data __initdata_memblock;
+static unsigned long memsize_ro __initdata_memblock;
+static unsigned long memsize_bss __initdata_memblock;
static bool memblock_memsize_tracking __initdata_memblock = true;

void __init memblock_memsize_enable_tracking(void)
@@ -2073,11 +2078,25 @@ void __init memblock_memsize_disable_tracking(void)
memblock_memsize_tracking = false;
}

+void __init memblock_memsize_mod_memmap_size(long size)
+{
+ memsize_memap += size;
+}
+
void memblock_memsize_mod_kernel_size(long size)
{
memsize_kinit += size;
}

+void __init memblock_memsize_kernel_code_data(unsigned long code, unsigned long data,
+ unsigned long ro, unsigned long bss)
+{
+ memsize_code = code;
+ memsize_data = data;
+ memsize_ro = ro;
+ memsize_bss = bss;
+}
+
static void __init_memblock memsize_get_valid_name(char *valid_name, const char *name)
{
char *head, *tail, *found;
@@ -2691,6 +2710,11 @@ static int memblock_memsize_show(struct seq_file *m, void *private)
struct memsize_rgn_struct *rgn;
unsigned long reserved = 0, reusable = 0, total;
unsigned long system = totalram_pages() << PAGE_SHIFT;
+ unsigned long etc;
+
+ etc = memsize_kinit;
+ etc -= memsize_code + memsize_data + memsize_ro + memsize_bss +
+ memsize_memap;

sort(memsize_rgn, memsize_rgn_count,
sizeof(memsize_rgn[0]), memsize_rgn_cmp, NULL);
@@ -2723,6 +2747,18 @@ static int memblock_memsize_show(struct seq_file *m, void *private)
DIV_ROUND_UP(memsize_kinit + reserved, SZ_1K));
seq_printf(m, " .kernel : %7lu KB\n",
DIV_ROUND_UP(memsize_kinit, SZ_1K));
+ seq_printf(m, " .text : %7lu KB\n"
+ " .rwdata : %7lu KB\n"
+ " .rodata : %7lu KB\n"
+ " .bss : %7lu KB\n"
+ " .memmap : %7lu KB\n"
+ " .etc : %7lu KB\n",
+ DIV_ROUND_UP(memsize_code, SZ_1K),
+ DIV_ROUND_UP(memsize_data, SZ_1K),
+ DIV_ROUND_UP(memsize_ro, SZ_1K),
+ DIV_ROUND_UP(memsize_bss, SZ_1K),
+ DIV_ROUND_UP(memsize_memap, SZ_1K),
+ DIV_ROUND_UP(etc, SZ_1K));
seq_printf(m, " .unusable : %7lu KB\n",
DIV_ROUND_UP(reserved, SZ_1K));
seq_printf(m, "System : %7lu KB\n",
diff --git a/mm/mm_init.c b/mm/mm_init.c
index f72b852bd5b8..45187904db49 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1587,8 +1587,10 @@ void __init *memmap_alloc(phys_addr_t size, phys_addr_t align,
MEMBLOCK_ALLOC_ACCESSIBLE,
nid);

- if (ptr && size > 0)
+ if (ptr && size > 0) {
page_init_poison(ptr, size);
+ memblock_memsize_mod_memmap_size((long)size);
+ }

return ptr;
}
@@ -2679,6 +2681,8 @@ static void __init mem_init_print_info(void)
init_data_size = __init_end - __init_begin;
init_code_size = _einittext - _sinittext;

+ memblock_memsize_kernel_code_data(codesize, datasize, rosize, bss_size);
+
/*
* Detect special cases and adjust section sizes accordingly:
* 1) .init.* may be embedded into .data sections
--
2.25.1