In the current code, the kernel command-line parameter mem= and memmap=
can not work well on MIPS, this patchset refactors the related code to
fix them.
For kdump on MIPS, if the users want to limit the memory region for the
capture kernel to avoid corrupting the memory image of the panic kernel,
use the parameter memmap=limit@base is the proper way, I will submit a
patch to use memmap=limit@base for kexec-tools after this patchset is
applied.
v3: Modify patch #3 to maintain compatibility for memmap=limit{$,#,!}base,
commented by Mike Rapoport, thank you.
v2: Add some new patches to support memmap=limit@base
Tiezhu Yang (4):
MIPS: Refactor early_parse_mem() to fix mem= parameter
memblock: Introduce memblock_mem_range_remove_map()
MIPS: Refactor early_parse_memmap() to fix memmap= parameter
MIPS: Remove not used variable usermem
arch/mips/kernel/setup.c | 69 ++++++++++++++++++++++--------------------------
include/linux/memblock.h | 1 +
mm/memblock.c | 9 +++++--
3 files changed, 40 insertions(+), 39 deletions(-)
--
2.1.0
This is preparation for supporting memmap=limit@base parameter,
no functionality change.
Signed-off-by: Tiezhu Yang <[email protected]>
---
include/linux/memblock.h | 1 +
mm/memblock.c | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 50ad196..e558d2c 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -482,6 +482,7 @@ phys_addr_t memblock_end_of_DRAM(void);
void memblock_enforce_memory_limit(phys_addr_t memory_limit);
void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
void memblock_mem_limit_remove_map(phys_addr_t limit);
+void memblock_mem_range_remove_map(phys_addr_t base, phys_addr_t limit);
bool memblock_is_memory(phys_addr_t addr);
bool memblock_is_map_memory(phys_addr_t addr);
bool memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
diff --git a/mm/memblock.c b/mm/memblock.c
index 1018e50..2476d15d 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1723,7 +1723,7 @@ void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
base + size, PHYS_ADDR_MAX);
}
-void __init memblock_mem_limit_remove_map(phys_addr_t limit)
+void __init memblock_mem_range_remove_map(phys_addr_t base, phys_addr_t limit)
{
phys_addr_t max_addr;
@@ -1736,7 +1736,12 @@ void __init memblock_mem_limit_remove_map(phys_addr_t limit)
if (max_addr == PHYS_ADDR_MAX)
return;
- memblock_cap_memory_range(0, max_addr);
+ memblock_cap_memory_range(base, max_addr);
+}
+
+void __init memblock_mem_limit_remove_map(phys_addr_t limit)
+{
+ memblock_mem_range_remove_map(0, limit);
}
static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)
--
2.1.0
According to Documentation/admin-guide/kernel-parameters.txt,
the kernel command-line parameter mem= means "Force usage of
a specific amount of memory", but when add "mem=3G" to the
command-line, kernel boot hangs in sparse_init().
This commit is similar with the implementation of the other
archs such as arm64, powerpc and riscv, refactor the function
early_parse_mem() and then use memblock_enforce_memory_limit()
to limit the memory size.
With this patch, when add "mem=3G" to the command-line, the
kernel boots successfully, we can see the following messages:
[ 0.000000] Memory limited to 3072MB
...
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000200000-0x000000000effffff]
[ 0.000000] node 0: [mem 0x0000000090200000-0x00000000ffffffff]
[ 0.000000] node 0: [mem 0x0000000120000000-0x00000001613fffff]
...
[ 0.000000] Memory: 3005280K/3145728K available (...)
After login, the output of free command is consistent with the
above log.
Signed-off-by: Tiezhu Yang <[email protected]>
---
arch/mips/kernel/setup.c | 26 +++++++++-----------------
1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f979adf..6b6d718 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -339,27 +339,15 @@ static void __init bootmem_init(void)
#endif /* CONFIG_SGI_IP27 */
static int usermem __initdata;
+static phys_addr_t memory_limit;
static int __init early_parse_mem(char *p)
{
- phys_addr_t start, size;
-
- /*
- * If a user specifies memory size, we
- * blow away any automatically generated
- * size.
- */
- if (usermem == 0) {
- usermem = 1;
- memblock_remove(memblock_start_of_DRAM(),
- memblock_end_of_DRAM() - memblock_start_of_DRAM());
- }
- start = 0;
- size = memparse(p, &p);
- if (*p == '@')
- start = memparse(p + 1, &p);
+ if (!p)
+ return 1;
- memblock_add(start, size);
+ memory_limit = memparse(p, &p) & PAGE_MASK;
+ pr_notice("Memory limited to %lldMB\n", memory_limit >> 20);
return 0;
}
@@ -678,6 +666,10 @@ static void __init arch_mem_init(char **cmdline_p)
memblock_reserve(__pa_symbol(&__nosave_begin),
__pa_symbol(&__nosave_end) - __pa_symbol(&__nosave_begin));
+ /* Limit the memory. */
+ memblock_enforce_memory_limit(memory_limit);
+ memblock_allow_resize();
+
early_memtest(PFN_PHYS(ARCH_PFN_OFFSET), PFN_PHYS(max_low_pfn));
}
--
2.1.0
Now, the variable usermem is not used any more, just remove it.
Signed-off-by: Tiezhu Yang <[email protected]>
---
arch/mips/kernel/setup.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index c940405..89fdaae 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -338,7 +338,6 @@ static void __init bootmem_init(void)
#endif /* CONFIG_SGI_IP27 */
-static int usermem __initdata;
static phys_addr_t memory_limit;
static phys_addr_t memory_base;
@@ -628,10 +627,6 @@ static void __init arch_mem_init(char **cmdline_p)
*cmdline_p = command_line;
parse_early_param();
-
- if (usermem)
- pr_info("User-defined physical RAM map overwrite\n");
-
check_kernel_sections_mem();
early_init_fdt_reserve_self();
--
2.1.0
Hi Tiezhu,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on hnaz-mm/master]
[also build test WARNING on linus/master v5.17-rc6 next-20220225]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Tiezhu-Yang/MIPS-Modify-mem-and-memmap-parameter/20220228-212554
base: https://github.com/hnaz/linux-mm master
config: mips-randconfig-r025-20220228 (https://download.01.org/0day-ci/archive/20220228/[email protected]/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project d271fc04d5b97b12e6b797c6067d3c96a8d7470e)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install mips cross compiling tool for clang build
# apt-get install binutils-mips-linux-gnu
# https://github.com/0day-ci/linux/commit/8e3bd7f4c0a4003c328ef2d816454dd50810b974
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Tiezhu-Yang/MIPS-Modify-mem-and-memmap-parameter/20220228-212554
git checkout 8e3bd7f4c0a4003c328ef2d816454dd50810b974
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=mips SHELL=/bin/bash arch/mips/kernel/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
>> arch/mips/kernel/setup.c:350:42: warning: format specifies type 'long long' but the argument has type 'phys_addr_t' (aka 'unsigned int') [-Wformat]
pr_notice("Memory limited to %lldMB\n", memory_limit >> 20);
~~~~ ^~~~~~~~~~~~~~~~~~
%u
include/linux/printk.h:509:36: note: expanded from macro 'pr_notice'
printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
~~~ ^~~~~~~~~~~
include/linux/printk.h:446:60: note: expanded from macro 'printk'
#define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
~~~ ^~~~~~~~~~~
include/linux/printk.h:418:19: note: expanded from macro 'printk_index_wrap'
_p_func(_fmt, ##__VA_ARGS__); \
~~~~ ^~~~~~~~~~~
1 warning generated.
vim +350 arch/mips/kernel/setup.c
343
344 static int __init early_parse_mem(char *p)
345 {
346 if (!p)
347 return 1;
348
349 memory_limit = memparse(p, &p) & PAGE_MASK;
> 350 pr_notice("Memory limited to %lldMB\n", memory_limit >> 20);
351
352 return 0;
353 }
354 early_param("mem", early_parse_mem);
355
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]