diff --git a/mm/memblock.c b/mm/memblock.c index 35c438146233..74a3c26df52e 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -20,6 +20,7 @@ #include #include #include +#include #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;