linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/4] MIPS: Modify mem= and memmap= parameter
@ 2022-03-05  6:21 Tiezhu Yang
  2022-03-05  6:21 ` [PATCH v5 1/4] memblock: Introduce memblock_mem_range_remove_map() Tiezhu Yang
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Tiezhu Yang @ 2022-03-05  6:21 UTC (permalink / raw)
  To: Thomas Bogendoerfer, Mike Rapoport, Andrew Morton
  Cc: Xuefeng Li, linux-mips, linux-mm, linux-kernel

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.

v5: Support mem=limit@base

v4: Fix some build warnings reported by kernel test robot

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):
  memblock: Introduce memblock_mem_range_remove_map()
  MIPS: Refactor early_parse_mem() to fix mem= parameter
  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, 42 insertions(+), 37 deletions(-)

-- 
2.1.0



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v5 1/4] memblock: Introduce memblock_mem_range_remove_map()
  2022-03-05  6:21 [PATCH v5 0/4] MIPS: Modify mem= and memmap= parameter Tiezhu Yang
@ 2022-03-05  6:21 ` Tiezhu Yang
  2022-03-05 13:28   ` Mike Rapoport
  2022-03-05  6:21 ` [PATCH v5 2/4] MIPS: Refactor early_parse_mem() to fix mem= parameter Tiezhu Yang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Tiezhu Yang @ 2022-03-05  6:21 UTC (permalink / raw)
  To: Thomas Bogendoerfer, Mike Rapoport, Andrew Morton
  Cc: Xuefeng Li, linux-mips, linux-mm, linux-kernel

This is preparation for supporting mem=limit@base and memmap=limit@base
parameters, no functionality change.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
---
 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



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v5 2/4] MIPS: Refactor early_parse_mem() to fix mem= parameter
  2022-03-05  6:21 [PATCH v5 0/4] MIPS: Modify mem= and memmap= parameter Tiezhu Yang
  2022-03-05  6:21 ` [PATCH v5 1/4] memblock: Introduce memblock_mem_range_remove_map() Tiezhu Yang
@ 2022-03-05  6:21 ` Tiezhu Yang
  2022-03-05  6:21 ` [PATCH v5 3/4] MIPS: Refactor early_parse_memmap() to fix memmap= parameter Tiezhu Yang
  2022-03-05  6:21 ` [PATCH v5 4/4] MIPS: Remove not used variable usermem Tiezhu Yang
  3 siblings, 0 replies; 6+ messages in thread
From: Tiezhu Yang @ 2022-03-05  6:21 UTC (permalink / raw)
  To: Thomas Bogendoerfer, Mike Rapoport, Andrew Morton
  Cc: Xuefeng Li, linux-mips, linux-mm, linux-kernel

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(), the same
issue appears when add "mem=3G@64M".

Here are the logs with "mem=3G@64M memblock=debug" added to
the kernel command line before the hang:

  [    0.000000] Linux version 5.17.0-rc3+ (loongson@linux)
  [    0.000000] CpuClock = 1800000000
  [    0.000000] The bridge chip is LS7A
  [    0.000000] CP0_Config3: CP0 16.3 (0xdc8030a0)
  [    0.000000] CP0_PageGrain: CP0 5.1 (0x28000000)
  [    0.000000] NUMA: Discovered 4 cpus on 1 nodes
  [    0.000000] Node0: mem_type:1, mem_start:0x200000, mem_size:0xee MB
  [    0.000000]        start_pfn:0x80, end_pfn:0x3c00, num_physpages:0x3b80
  [    0.000000] Node0: mem_type:2, mem_start:0x90200000, mem_size:0x6fe MB
  [    0.000000]        start_pfn:0x24080, end_pfn:0x40000, num_physpages:0x1fb00
  [    0.000000] Node0: mem_type:2, mem_start:0x120000000, mem_size:0x1600 MB
  [    0.000000]        start_pfn:0x48000, end_pfn:0xa0000, num_physpages:0x77b00
  [    0.000000] Node0's addrspace_offset is 0x0
  [    0.000000] Node0: start_pfn=0x80, end_pfn=0xa0000
  [    0.000000] NUMA: set cpumask cpu 0 on node 0
  [    0.000000] NUMA: set cpumask cpu 1 on node 0
  [    0.000000] NUMA: set cpumask cpu 2 on node 0
  [    0.000000] NUMA: set cpumask cpu 3 on node 0
  [    0.000000] printk: bootconsole [early0] enabled
  [    0.000000] CPU0 revision is: 0014c001 (ICT Loongson-3)
  [    0.000000] FPU revision is: 00f70501
  [    0.000000] MSA revision is: 00060140
  [    0.000000] OF: fdt: No chosen node found, continuing without
  [    0.000000] MIPS: machine is loongson,loongson64g-4core-ls7a
  [    0.000000] User-defined physical RAM map overwrite
  [    0.000000] Kernel sections are not in the memory maps
  [    0.000000] memblock_add: [0x0000000000200000-0x000000000231185f] setup_arch+0x140/0x794
  [    0.000000] memblock_reserve: [0x0000000001260520-0x0000000001262560] setup_arch+0x148/0x794
  [    0.000000] Initrd not found or empty - disabling initrd
  [    0.000000] memblock_alloc_try_nid: 8257 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x30/0x60
  [    0.000000] memblock_reserve: [0x0000000004000000-0x0000000004002040] memblock_alloc_range_nid+0xf0/0x178
  [    0.000000] memblock_alloc_try_nid: 37972 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x30/0x60
  [    0.000000] memblock_reserve: [0x0000000004002048-0x000000000400b49b] memblock_alloc_range_nid+0xf0/0x178

As Mike Rapoport said, the kernel lives in 0x200000 and using
mem=3G@64M removes the memory with the kernel and also makes
the kernel think there is memory between 0x400000 and 0xf000000
while there seem to be a hole up to 0x90200000. This definitely
can be reason for the hangs.

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_mem_range_remove_map()
to support mem=limit and mem=limit@base (if @base is omitted,
it is equivalent to mem=limit).

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 0MB-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 (...)

When add "mem=3G@64M" to the command-line, the kernel boots successfully,
we can see the following messages:

  [    0.000000] Memory limited to 64MB-3136MB
  ...
  [    0.000000] Early memory node ranges
  [    0.000000]   node   0: [mem 0x0000000004000000-0x000000000effffff]
  [    0.000000]   node   0: [mem 0x0000000090200000-0x00000000ffffffff]
  [    0.000000]   node   0: [mem 0x0000000120000000-0x00000001653fffff]
  ...
  [    0.000000] Memory: 3070816K/3147776K available (...)

After login, the output of free command is consistent with the
above log.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
---
 arch/mips/kernel/setup.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f979adf..de5824bc 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -339,27 +339,20 @@ 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;
 
 static int __init early_parse_mem(char *p)
 {
-	phys_addr_t start, size;
+	if (!p)
+		return 1;
 
-	/*
-	 * 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);
+	memory_limit = memparse(p, &p) & PAGE_MASK;
 	if (*p == '@')
-		start = memparse(p + 1, &p);
+		memory_base = memparse(p + 1, &p) & PAGE_MASK;
 
-	memblock_add(start, size);
+	pr_notice("Memory limited to %lluMB-%lluMB\n",
+		  (u64)memory_base >> 20, (u64)(memory_base + memory_limit) >> 20);
 
 	return 0;
 }
@@ -678,6 +671,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_mem_range_remove_map(memory_base, memory_limit);
+	memblock_allow_resize();
+
 	early_memtest(PFN_PHYS(ARCH_PFN_OFFSET), PFN_PHYS(max_low_pfn));
 }
 
-- 
2.1.0



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v5 3/4] MIPS: Refactor early_parse_memmap() to fix memmap= parameter
  2022-03-05  6:21 [PATCH v5 0/4] MIPS: Modify mem= and memmap= parameter Tiezhu Yang
  2022-03-05  6:21 ` [PATCH v5 1/4] memblock: Introduce memblock_mem_range_remove_map() Tiezhu Yang
  2022-03-05  6:21 ` [PATCH v5 2/4] MIPS: Refactor early_parse_mem() to fix mem= parameter Tiezhu Yang
@ 2022-03-05  6:21 ` Tiezhu Yang
  2022-03-05  6:21 ` [PATCH v5 4/4] MIPS: Remove not used variable usermem Tiezhu Yang
  3 siblings, 0 replies; 6+ messages in thread
From: Tiezhu Yang @ 2022-03-05  6:21 UTC (permalink / raw)
  To: Thomas Bogendoerfer, Mike Rapoport, Andrew Morton
  Cc: Xuefeng Li, linux-mips, linux-mm, linux-kernel

According to Documentation/admin-guide/kernel-parameters.txt,
the kernel command-line parameter memmap= means "Force usage
of a specific region of memory", but when add "memmap=3G@64M"
to the command-line, kernel boot hangs in sparse_init().

In order to support memmap=limit@base, refactor the function
early_parse_memmap() to limit the memory region.

With this patch, when add "memmap=3G@64M" to the command-line,
the kernel boots successfully, we can see the following messages:

  [    0.000000] Memory limited to 64MB-3136MB
  ...
  [    0.000000] Early memory node ranges
  [    0.000000]   node   0: [mem 0x0000000004000000-0x000000000effffff]
  [    0.000000]   node   0: [mem 0x0000000090200000-0x00000000ffffffff]
  [    0.000000]   node   0: [mem 0x0000000120000000-0x00000001653fffff]
  ...
  [    0.000000] Memory: 3070816K/3147776K available (...)

After login, the output of free command is consistent with the
above log.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
---
 arch/mips/kernel/setup.c | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index de5824bc..6b7229f 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -361,7 +361,6 @@ early_param("mem", early_parse_mem);
 static int __init early_parse_memmap(char *p)
 {
 	char *oldp;
-	u64 start_at, mem_size;
 
 	if (!p)
 		return -EINVAL;
@@ -372,30 +371,38 @@ static int __init early_parse_memmap(char *p)
 	}
 
 	oldp = p;
-	mem_size = memparse(p, &p);
+	memory_limit = memparse(p, &p) & PAGE_MASK;
 	if (p == oldp)
 		return -EINVAL;
 
 	if (*p == '@') {
-		start_at = memparse(p+1, &p);
-		memblock_add(start_at, mem_size);
+		memory_base = memparse(p + 1, &p) & PAGE_MASK;
+	} else if (*p == '$') {
+		memory_base = memparse(p+1, &p) & PAGE_MASK;
+		memblock_reserve(memory_base, memory_limit);
+		pr_notice("Memory reserved to %lluMB-%lluMB\n",
+			  (u64)memory_base >> 20, (u64)(memory_base + memory_limit) >> 20);
+		memory_base = 0;
+		memory_limit = 0;
+		return 0;
 	} else if (*p == '#') {
-		pr_err("\"memmap=nn#ss\" (force ACPI data) invalid on MIPS\n");
+		pr_err("\"memmap=nn#ss\" invalid on MIPS\n");
+		memory_limit = 0;
+		return -EINVAL;
+	} else if (*p == '!') {
+		pr_err("\"memmap=nn!ss\" invalid on MIPS\n");
+		memory_limit = 0;
 		return -EINVAL;
-	} else if (*p == '$') {
-		start_at = memparse(p+1, &p);
-		memblock_add(start_at, mem_size);
-		memblock_reserve(start_at, mem_size);
 	} else {
-		pr_err("\"memmap\" invalid format!\n");
+		pr_err("Unrecognized memmap syntax: %s\n", p);
+		memory_limit = 0;
 		return -EINVAL;
 	}
 
-	if (*p == '\0') {
-		usermem = 1;
-		return 0;
-	} else
-		return -EINVAL;
+	pr_notice("Memory limited to %lluMB-%lluMB\n",
+		  (u64)memory_base >> 20, (u64)(memory_base + memory_limit) >> 20);
+
+	return *p == '\0' ? 0 : -EINVAL;
 }
 early_param("memmap", early_parse_memmap);
 
-- 
2.1.0



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v5 4/4] MIPS: Remove not used variable usermem
  2022-03-05  6:21 [PATCH v5 0/4] MIPS: Modify mem= and memmap= parameter Tiezhu Yang
                   ` (2 preceding siblings ...)
  2022-03-05  6:21 ` [PATCH v5 3/4] MIPS: Refactor early_parse_memmap() to fix memmap= parameter Tiezhu Yang
@ 2022-03-05  6:21 ` Tiezhu Yang
  3 siblings, 0 replies; 6+ messages in thread
From: Tiezhu Yang @ 2022-03-05  6:21 UTC (permalink / raw)
  To: Thomas Bogendoerfer, Mike Rapoport, Andrew Morton
  Cc: Xuefeng Li, linux-mips, linux-mm, linux-kernel

Now, the variable usermem is not used any more, just remove it.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
---
 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 6b7229f..e9408a5 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;
 
@@ -632,10 +631,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



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v5 1/4] memblock: Introduce memblock_mem_range_remove_map()
  2022-03-05  6:21 ` [PATCH v5 1/4] memblock: Introduce memblock_mem_range_remove_map() Tiezhu Yang
@ 2022-03-05 13:28   ` Mike Rapoport
  0 siblings, 0 replies; 6+ messages in thread
From: Mike Rapoport @ 2022-03-05 13:28 UTC (permalink / raw)
  To: Tiezhu Yang
  Cc: Thomas Bogendoerfer, Andrew Morton, Xuefeng Li, linux-mips,
	linux-mm, linux-kernel

On Sat, Mar 05, 2022 at 02:21:26PM +0800, Tiezhu Yang wrote:
> This is preparation for supporting mem=limit@base and memmap=limit@base
> parameters, no functionality change.
> 
> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>

NAK.

We already have enough memory capping interfaces in memblock, we don't need
yet another one.

> ---
>  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
> 

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-03-05 13:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-05  6:21 [PATCH v5 0/4] MIPS: Modify mem= and memmap= parameter Tiezhu Yang
2022-03-05  6:21 ` [PATCH v5 1/4] memblock: Introduce memblock_mem_range_remove_map() Tiezhu Yang
2022-03-05 13:28   ` Mike Rapoport
2022-03-05  6:21 ` [PATCH v5 2/4] MIPS: Refactor early_parse_mem() to fix mem= parameter Tiezhu Yang
2022-03-05  6:21 ` [PATCH v5 3/4] MIPS: Refactor early_parse_memmap() to fix memmap= parameter Tiezhu Yang
2022-03-05  6:21 ` [PATCH v5 4/4] MIPS: Remove not used variable usermem Tiezhu Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).