All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] mips: Fix related problems in kdump operation
@ 2021-04-22  2:24 ` Youling Tang
  0 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

1. Fix the "mem=" parameter parsing problem.
2. Solve the problem that panic may be triggered due to insufficient memory
when entering the capture kernel.
3. Fix the problem that the captured production kernel data may be destroyed.

Youling Tang (4):
  MIPS: Fix cmdline "mem=" parameter parsing
  mips: kdump: Capture kernel should be able to see old memories
  mips: kdump: Reserve extra memory for crash dump
  mips: kdump: Reserve old memory to avoid the destruction of production
    kernel data

 arch/mips/kernel/setup.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 79 insertions(+), 3 deletions(-)

-- 
2.1.0


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

* [PATCH v2 0/4] mips: Fix related problems in kdump operation
@ 2021-04-22  2:24 ` Youling Tang
  0 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

1. Fix the "mem=" parameter parsing problem.
2. Solve the problem that panic may be triggered due to insufficient memory
when entering the capture kernel.
3. Fix the problem that the captured production kernel data may be destroyed.

Youling Tang (4):
  MIPS: Fix cmdline "mem=" parameter parsing
  mips: kdump: Capture kernel should be able to see old memories
  mips: kdump: Reserve extra memory for crash dump
  mips: kdump: Reserve old memory to avoid the destruction of production
    kernel data

 arch/mips/kernel/setup.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 79 insertions(+), 3 deletions(-)

-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v2 1/4] MIPS: Fix cmdline "mem=" parameter parsing
  2021-04-22  2:24 ` Youling Tang
@ 2021-04-22  2:24   ` Youling Tang
  -1 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

This problem may only occur on NUMA platforms. When machine start with the
"mem=" parameter on Loongson64, it cannot boot. When parsing the "mem="
parameter, first remove all RAM, and then add memory through memblock_add(),
which causes the newly added memory to be located on MAX_NUMNODES.

The solution is to add the current "mem=" parameter range to the memory area
of the corresponding node, instead of adding all of it to the MAX_NUMNODES
node area. Get the node number corresponding to the "mem=" parameter range
through pa_to_nid(), and then add it to the corresponding node through
memblock_add_node().

Signed-off-by: Jinyang He <hejinyang@loongson.cn>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
v2:
 - Include the mmzone.h header file, to solve the "error: implicit
   declaration of function'pa_to_nid'" compilation error.

 arch/mips/kernel/setup.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 279be01..9338520 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -37,6 +37,7 @@
 #include <asm/cdmm.h>
 #include <asm/cpu.h>
 #include <asm/debug.h>
+#include <asm/mmzone.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp-ops.h>
@@ -359,7 +360,7 @@ static int __init early_parse_mem(char *p)
 	if (*p == '@')
 		start = memparse(p + 1, &p);
 
-	memblock_add(start, size);
+	memblock_add_node(start, size, pa_to_nid(start));
 
 	return 0;
 }
-- 
2.1.0


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

* [PATCH v2 1/4] MIPS: Fix cmdline "mem=" parameter parsing
@ 2021-04-22  2:24   ` Youling Tang
  0 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

This problem may only occur on NUMA platforms. When machine start with the
"mem=" parameter on Loongson64, it cannot boot. When parsing the "mem="
parameter, first remove all RAM, and then add memory through memblock_add(),
which causes the newly added memory to be located on MAX_NUMNODES.

The solution is to add the current "mem=" parameter range to the memory area
of the corresponding node, instead of adding all of it to the MAX_NUMNODES
node area. Get the node number corresponding to the "mem=" parameter range
through pa_to_nid(), and then add it to the corresponding node through
memblock_add_node().

Signed-off-by: Jinyang He <hejinyang@loongson.cn>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
v2:
 - Include the mmzone.h header file, to solve the "error: implicit
   declaration of function'pa_to_nid'" compilation error.

 arch/mips/kernel/setup.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 279be01..9338520 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -37,6 +37,7 @@
 #include <asm/cdmm.h>
 #include <asm/cpu.h>
 #include <asm/debug.h>
+#include <asm/mmzone.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp-ops.h>
@@ -359,7 +360,7 @@ static int __init early_parse_mem(char *p)
 	if (*p == '@')
 		start = memparse(p + 1, &p);
 
-	memblock_add(start, size);
+	memblock_add_node(start, size, pa_to_nid(start));
 
 	return 0;
 }
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v2 2/4] mips: kdump: Capture kernel should be able to see old memories
  2021-04-22  2:24 ` Youling Tang
@ 2021-04-22  2:24   ` Youling Tang
  -1 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

From: Huacai Chen <chenhc@lemote.com>

kexec-tools use mem=X@Y to pass usable memories to capture kernel, but
in commit a94e4f24ec836c8984f83959 ("MIPS: init: Drop boot_mem_map") all
BIOS passed memories are removed by early_parse_mem(). I think this is
reasonable for a normal kernel but not for a capture kernel, because a
capture kernel should be able to see all old memories, even though it is
not supposed to use them.

Fixes: a94e4f24ec836c8984f83959 ("MIPS: init: Drop boot_mem_map")
Signed-off-by: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
v2:
- Determine whether it is a capture kernel by judging whether there
  is an "elfcorehdr" parameter in the cmdline.

 arch/mips/kernel/setup.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 9338520..1bc8a9cc 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -352,8 +352,13 @@ static int __init early_parse_mem(char *p)
 	 */
 	if (usermem == 0) {
 		usermem = 1;
-		memblock_remove(memblock_start_of_DRAM(),
-			memblock_end_of_DRAM() - memblock_start_of_DRAM());
+		/*
+		 * During the kdump operation, the old memory should be
+		 * visible to the capture kernel.
+		 */
+		if (!strstr(boot_command_line, "elfcorehdr"))
+			memblock_remove(memblock_start_of_DRAM(),
+				memblock_end_of_DRAM() - memblock_start_of_DRAM());
 	}
 	start = 0;
 	size = memparse(p, &p);
-- 
2.1.0


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

* [PATCH v2 2/4] mips: kdump: Capture kernel should be able to see old memories
@ 2021-04-22  2:24   ` Youling Tang
  0 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

From: Huacai Chen <chenhc@lemote.com>

kexec-tools use mem=X@Y to pass usable memories to capture kernel, but
in commit a94e4f24ec836c8984f83959 ("MIPS: init: Drop boot_mem_map") all
BIOS passed memories are removed by early_parse_mem(). I think this is
reasonable for a normal kernel but not for a capture kernel, because a
capture kernel should be able to see all old memories, even though it is
not supposed to use them.

Fixes: a94e4f24ec836c8984f83959 ("MIPS: init: Drop boot_mem_map")
Signed-off-by: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
v2:
- Determine whether it is a capture kernel by judging whether there
  is an "elfcorehdr" parameter in the cmdline.

 arch/mips/kernel/setup.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 9338520..1bc8a9cc 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -352,8 +352,13 @@ static int __init early_parse_mem(char *p)
 	 */
 	if (usermem == 0) {
 		usermem = 1;
-		memblock_remove(memblock_start_of_DRAM(),
-			memblock_end_of_DRAM() - memblock_start_of_DRAM());
+		/*
+		 * During the kdump operation, the old memory should be
+		 * visible to the capture kernel.
+		 */
+		if (!strstr(boot_command_line, "elfcorehdr"))
+			memblock_remove(memblock_start_of_DRAM(),
+				memblock_end_of_DRAM() - memblock_start_of_DRAM());
 	}
 	start = 0;
 	size = memparse(p, &p);
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v2 3/4] mips: kdump: Reserve extra memory for crash dump
  2021-04-22  2:24 ` Youling Tang
@ 2021-04-22  2:24   ` Youling Tang
  -1 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

From: Huacai Chen <chenhc@lemote.com>

Traditionally, MIPS's contiguous low memory can be as less as 256M, so
crashkernel=X@Y may be unable to large enough in some cases. Moreover,
for the "multi numa node + sparse memory model" case, it is attempt to
allocate section_mem_maps on every node. Thus, if the total memory of a
node is more than 1GB, we reserve the top 128MB for the capture kernel.

This 128M will be reserved only if the following conditions are met:
1. The configuration option CONFIG_KEXEC is y.
2. A valid "crashkernel=" parameter has been added to the command line.
3. The total memory of a node is greater than 1G.

Signed-off-by: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
v2:
- New patch.

 arch/mips/kernel/setup.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 1bc8a9cc..af2c860 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -492,6 +492,25 @@ static void __init request_crashkernel(struct resource *res)
 			(unsigned long)(resource_size(&crashk_res) >> 20),
 			(unsigned long)(crashk_res.start  >> 20));
 }
+
+/*
+ * Traditionally, MIPS's contiguous low memory is 256M, so crashkernel=X@Y is
+ * unable to be large enough in some cases. Thus, if the total memory of a node
+ * is more than 1GB, we reserve the top 128MB for the capture kernel.
+ */
+static void reserve_crashm_region(int node, unsigned long s0, unsigned long e0)
+{
+	if (crashk_res.start == crashk_res.end)
+		return;
+
+	if ((e0 - s0) <= (SZ_1G >> PAGE_SHIFT))
+		return;
+
+	s0 = e0 - (SZ_128M >> PAGE_SHIFT);
+
+	memblock_reserve(PFN_PHYS(s0), (e0 - s0) << PAGE_SHIFT);
+}
+
 #else /* !defined(CONFIG_KEXEC)		*/
 static void __init mips_parse_crashkernel(void)
 {
@@ -500,6 +519,10 @@ static void __init mips_parse_crashkernel(void)
 static void __init request_crashkernel(struct resource *res)
 {
 }
+
+static void reserve_crashm_region(int node, unsigned long s0, unsigned long e0)
+{
+}
 #endif /* !defined(CONFIG_KEXEC)  */
 
 static void __init check_kernel_sections_mem(void)
@@ -627,6 +650,9 @@ static void __init bootcmdline_init(void)
  */
 static void __init arch_mem_init(char **cmdline_p)
 {
+	unsigned int node;
+	unsigned long start_pfn, end_pfn;
+
 	/* call board setup routine */
 	plat_mem_setup();
 	memblock_set_bottom_up(true);
@@ -666,6 +692,12 @@ static void __init arch_mem_init(char **cmdline_p)
 	if (crashk_res.start != crashk_res.end)
 		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
 #endif
+
+	for_each_online_node(node) {
+		get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
+		reserve_crashm_region(node, start_pfn, end_pfn);
+	}
+
 	device_tree_init();
 
 	/*
-- 
2.1.0


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

* [PATCH v2 3/4] mips: kdump: Reserve extra memory for crash dump
@ 2021-04-22  2:24   ` Youling Tang
  0 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

From: Huacai Chen <chenhc@lemote.com>

Traditionally, MIPS's contiguous low memory can be as less as 256M, so
crashkernel=X@Y may be unable to large enough in some cases. Moreover,
for the "multi numa node + sparse memory model" case, it is attempt to
allocate section_mem_maps on every node. Thus, if the total memory of a
node is more than 1GB, we reserve the top 128MB for the capture kernel.

This 128M will be reserved only if the following conditions are met:
1. The configuration option CONFIG_KEXEC is y.
2. A valid "crashkernel=" parameter has been added to the command line.
3. The total memory of a node is greater than 1G.

Signed-off-by: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
v2:
- New patch.

 arch/mips/kernel/setup.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 1bc8a9cc..af2c860 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -492,6 +492,25 @@ static void __init request_crashkernel(struct resource *res)
 			(unsigned long)(resource_size(&crashk_res) >> 20),
 			(unsigned long)(crashk_res.start  >> 20));
 }
+
+/*
+ * Traditionally, MIPS's contiguous low memory is 256M, so crashkernel=X@Y is
+ * unable to be large enough in some cases. Thus, if the total memory of a node
+ * is more than 1GB, we reserve the top 128MB for the capture kernel.
+ */
+static void reserve_crashm_region(int node, unsigned long s0, unsigned long e0)
+{
+	if (crashk_res.start == crashk_res.end)
+		return;
+
+	if ((e0 - s0) <= (SZ_1G >> PAGE_SHIFT))
+		return;
+
+	s0 = e0 - (SZ_128M >> PAGE_SHIFT);
+
+	memblock_reserve(PFN_PHYS(s0), (e0 - s0) << PAGE_SHIFT);
+}
+
 #else /* !defined(CONFIG_KEXEC)		*/
 static void __init mips_parse_crashkernel(void)
 {
@@ -500,6 +519,10 @@ static void __init mips_parse_crashkernel(void)
 static void __init request_crashkernel(struct resource *res)
 {
 }
+
+static void reserve_crashm_region(int node, unsigned long s0, unsigned long e0)
+{
+}
 #endif /* !defined(CONFIG_KEXEC)  */
 
 static void __init check_kernel_sections_mem(void)
@@ -627,6 +650,9 @@ static void __init bootcmdline_init(void)
  */
 static void __init arch_mem_init(char **cmdline_p)
 {
+	unsigned int node;
+	unsigned long start_pfn, end_pfn;
+
 	/* call board setup routine */
 	plat_mem_setup();
 	memblock_set_bottom_up(true);
@@ -666,6 +692,12 @@ static void __init arch_mem_init(char **cmdline_p)
 	if (crashk_res.start != crashk_res.end)
 		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
 #endif
+
+	for_each_online_node(node) {
+		get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
+		reserve_crashm_region(node, start_pfn, end_pfn);
+	}
+
 	device_tree_init();
 
 	/*
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v2 4/4] mips: kdump: Reserve old memory to avoid the destruction of production kernel data
  2021-04-22  2:24 ` Youling Tang
@ 2021-04-22  2:24   ` Youling Tang
  -1 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

From: Huacai Chen <chenhc@lemote.com>

Memory layout:

+---------+ end_pfn(e0+128M)
|         |
+---------+ e0
|         |
|         |
|         |
+---------+ e1(crashk_res.start)
|         |
|         |
|         |
+---------+ s1(crashk_res.start)
|         |
+---------+ s0(start_pfn)

[1] When producing the kernel:
Reserve the crashkernel space through crashkernel="YM@XM", so that
[s1, e1] is reserved for the capture kernel.

If the available memory range is greater than 1G, an additional 128M
range is reserved from top to bottom for the capture kernel (ie
[e0, end_pfn] range). The advantage of this is that it can make more
memory available to the capture kernel and avoid triggering insufficient
memory, resulting in panic.

[2] When capturing the kernel:
Finally, the "mem=" parameter is automatically added through kexec-tools
(the "mem=" parameter actually comes from the "crashkernel=" parameter,
and the scope is the same).

It is necessary to reserve the available memory area of the previous
production kernel to avoid the captured data of the production kernel
from being destroyed. If this area in the memory is not reserved, the
captured data will be destroyed, the generated vmcore file is invalid
and cannot be parsed by the crash-utility.

[3] Only consider the memory situation of kdump operation as follows:
1. Production kernel:
memblock.reserve: [s1, e1] and [e0, end_pfn] (Memory is reserved)
memblock.memory:  [s0, s1] and [e1, e0]      (Memory available)

2. Capture kernel:
memblock.reserve: [s0, s1] and [e1, e0]      (Memory is reserved)
memblock.memory:  [s1, e1] and [e0, end_pfn] (Memory available)

In conclusion,[s0, s1] and [e1, e0] memory areas should be reserved.

Signed-off-by: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
v2:
 - New patch.

 arch/mips/kernel/setup.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index af2c860..aa89f28 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -55,6 +55,8 @@ EXPORT_SYMBOL(cpu_data);
 struct screen_info screen_info;
 #endif
 
+static phys_addr_t crashmem_start, crashmem_size;
+
 /*
  * Setup information
  *
@@ -367,6 +369,11 @@ static int __init early_parse_mem(char *p)
 
 	memblock_add_node(start, size, pa_to_nid(start));
 
+	if (strstr(boot_command_line, "elfcorehdr") && start && size) {
+		crashmem_start = start;
+		crashmem_size = size;
+	}
+
 	return 0;
 }
 early_param("mem", early_parse_mem);
@@ -525,6 +532,36 @@ static void reserve_crashm_region(int node, unsigned long s0, unsigned long e0)
 }
 #endif /* !defined(CONFIG_KEXEC)  */
 
+/*
+ * After the kdump operation is performed to enter the capture kernel, the
+ * memory area used by the previous production kernel should be reserved to
+ * avoid destroy to the captured data.
+ */
+static void reserve_oldmem_region(int node, unsigned long s0, unsigned long e0)
+{
+	unsigned long s1, e1;
+
+	if (!is_kdump_kernel())
+		return;
+
+	if ((e0 - s0) > (SZ_1G >> PAGE_SHIFT))
+		e0 = e0 - (SZ_128M >> PAGE_SHIFT);
+
+	/* crashmem_start is crashk_res reserved by primary production kernel */
+	s1 = PFN_UP(crashmem_start);
+	e1 = PFN_DOWN(crashmem_start + crashmem_size);
+
+	if (s1 == 0)
+		return;
+
+	if (node == 0) {
+		memblock_reserve(PFN_PHYS(s0), (s1 - s0) << PAGE_SHIFT);
+		memblock_reserve(PFN_PHYS(e1), (e0 - e1) << PAGE_SHIFT);
+	} else {
+		memblock_reserve(PFN_PHYS(s0), (e0 - s0) << PAGE_SHIFT);
+	}
+}
+
 static void __init check_kernel_sections_mem(void)
 {
 	phys_addr_t start = __pa_symbol(&_text);
@@ -696,6 +733,7 @@ static void __init arch_mem_init(char **cmdline_p)
 	for_each_online_node(node) {
 		get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
 		reserve_crashm_region(node, start_pfn, end_pfn);
+		reserve_oldmem_region(node, start_pfn, end_pfn);
 	}
 
 	device_tree_init();
-- 
2.1.0


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

* [PATCH v2 4/4] mips: kdump: Reserve old memory to avoid the destruction of production kernel data
@ 2021-04-22  2:24   ` Youling Tang
  0 siblings, 0 replies; 10+ messages in thread
From: Youling Tang @ 2021-04-22  2:24 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Jiaxun Yang, Baoquan He, Huacai Chen, Jinyang He, kexec,
	linux-mips, linux-kernel

From: Huacai Chen <chenhc@lemote.com>

Memory layout:

+---------+ end_pfn(e0+128M)
|         |
+---------+ e0
|         |
|         |
|         |
+---------+ e1(crashk_res.start)
|         |
|         |
|         |
+---------+ s1(crashk_res.start)
|         |
+---------+ s0(start_pfn)

[1] When producing the kernel:
Reserve the crashkernel space through crashkernel="YM@XM", so that
[s1, e1] is reserved for the capture kernel.

If the available memory range is greater than 1G, an additional 128M
range is reserved from top to bottom for the capture kernel (ie
[e0, end_pfn] range). The advantage of this is that it can make more
memory available to the capture kernel and avoid triggering insufficient
memory, resulting in panic.

[2] When capturing the kernel:
Finally, the "mem=" parameter is automatically added through kexec-tools
(the "mem=" parameter actually comes from the "crashkernel=" parameter,
and the scope is the same).

It is necessary to reserve the available memory area of the previous
production kernel to avoid the captured data of the production kernel
from being destroyed. If this area in the memory is not reserved, the
captured data will be destroyed, the generated vmcore file is invalid
and cannot be parsed by the crash-utility.

[3] Only consider the memory situation of kdump operation as follows:
1. Production kernel:
memblock.reserve: [s1, e1] and [e0, end_pfn] (Memory is reserved)
memblock.memory:  [s0, s1] and [e1, e0]      (Memory available)

2. Capture kernel:
memblock.reserve: [s0, s1] and [e1, e0]      (Memory is reserved)
memblock.memory:  [s1, e1] and [e0, end_pfn] (Memory available)

In conclusion,[s0, s1] and [e1, e0] memory areas should be reserved.

Signed-off-by: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
---
v2:
 - New patch.

 arch/mips/kernel/setup.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index af2c860..aa89f28 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -55,6 +55,8 @@ EXPORT_SYMBOL(cpu_data);
 struct screen_info screen_info;
 #endif
 
+static phys_addr_t crashmem_start, crashmem_size;
+
 /*
  * Setup information
  *
@@ -367,6 +369,11 @@ static int __init early_parse_mem(char *p)
 
 	memblock_add_node(start, size, pa_to_nid(start));
 
+	if (strstr(boot_command_line, "elfcorehdr") && start && size) {
+		crashmem_start = start;
+		crashmem_size = size;
+	}
+
 	return 0;
 }
 early_param("mem", early_parse_mem);
@@ -525,6 +532,36 @@ static void reserve_crashm_region(int node, unsigned long s0, unsigned long e0)
 }
 #endif /* !defined(CONFIG_KEXEC)  */
 
+/*
+ * After the kdump operation is performed to enter the capture kernel, the
+ * memory area used by the previous production kernel should be reserved to
+ * avoid destroy to the captured data.
+ */
+static void reserve_oldmem_region(int node, unsigned long s0, unsigned long e0)
+{
+	unsigned long s1, e1;
+
+	if (!is_kdump_kernel())
+		return;
+
+	if ((e0 - s0) > (SZ_1G >> PAGE_SHIFT))
+		e0 = e0 - (SZ_128M >> PAGE_SHIFT);
+
+	/* crashmem_start is crashk_res reserved by primary production kernel */
+	s1 = PFN_UP(crashmem_start);
+	e1 = PFN_DOWN(crashmem_start + crashmem_size);
+
+	if (s1 == 0)
+		return;
+
+	if (node == 0) {
+		memblock_reserve(PFN_PHYS(s0), (s1 - s0) << PAGE_SHIFT);
+		memblock_reserve(PFN_PHYS(e1), (e0 - e1) << PAGE_SHIFT);
+	} else {
+		memblock_reserve(PFN_PHYS(s0), (e0 - s0) << PAGE_SHIFT);
+	}
+}
+
 static void __init check_kernel_sections_mem(void)
 {
 	phys_addr_t start = __pa_symbol(&_text);
@@ -696,6 +733,7 @@ static void __init arch_mem_init(char **cmdline_p)
 	for_each_online_node(node) {
 		get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
 		reserve_crashm_region(node, start_pfn, end_pfn);
+		reserve_oldmem_region(node, start_pfn, end_pfn);
 	}
 
 	device_tree_init();
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

end of thread, other threads:[~2021-04-22  2:25 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-22  2:24 [PATCH v2 0/4] mips: Fix related problems in kdump operation Youling Tang
2021-04-22  2:24 ` Youling Tang
2021-04-22  2:24 ` [PATCH v2 1/4] MIPS: Fix cmdline "mem=" parameter parsing Youling Tang
2021-04-22  2:24   ` Youling Tang
2021-04-22  2:24 ` [PATCH v2 2/4] mips: kdump: Capture kernel should be able to see old memories Youling Tang
2021-04-22  2:24   ` Youling Tang
2021-04-22  2:24 ` [PATCH v2 3/4] mips: kdump: Reserve extra memory for crash dump Youling Tang
2021-04-22  2:24   ` Youling Tang
2021-04-22  2:24 ` [PATCH v2 4/4] mips: kdump: Reserve old memory to avoid the destruction of production kernel data Youling Tang
2021-04-22  2:24   ` Youling Tang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.