[PATCH v2 2/4] powerpc/fadump: exclude memory holes while reserving memory in second kernel.

Mahesh J Salgaonkar mahesh at linux.vnet.ibm.com
Thu Mar 29 14:58:11 AEDT 2018


From: Mahesh Salgaonkar <mahesh at linux.vnet.ibm.com>

The second kernel, during early boot after the crash, reserves rest of
the memory above boot memory size to make sure it does not touch any of the
dump memory area. It uses memblock_reserve() that reserves the specified
memory region irrespective of memory holes present within that region.
There are chances where previous kernel would have hot removed some of
its memory leaving memory holes behind. In such cases fadump kernel reports
incorrect number of reserved pages through arch_reserved_kernel_pages() hook
causing kernel to hang or panic.

Fix this by excluding memory holes while reserving rest of the memory
above boot memory size during second kernel boot after crash.

Signed-off-by: Mahesh Salgaonkar <mahesh at linux.vnet.ibm.com>
---
 arch/powerpc/kernel/fadump.c |   19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 2098583c935f..9d75619cac28 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -434,6 +434,23 @@ static inline unsigned long get_fadump_metadata_base(
 			be64_to_cpu(fdm_active->rmr_region.source_len));
 }
 
+static void fadump_memblock_reserve(unsigned long base, unsigned long size)
+{
+	struct memblock_region *reg;
+	unsigned long start, end;
+
+	for_each_memblock(memory, reg) {
+		start = (unsigned long)reg->base;
+		end = start + (unsigned long)reg->size;
+
+		if ((start >= base) && (start < (base + size))) {
+			if (end > (base + size))
+				end = base + size;
+			memblock_reserve(start, end - start);
+		}
+	}
+}
+
 int __init fadump_reserve_mem(void)
 {
 	unsigned long base, size, memory_boundary;
@@ -488,7 +505,7 @@ int __init fadump_reserve_mem(void)
 		 */
 		base = fw_dump.boot_memory_size;
 		size = memory_boundary - base;
-		memblock_reserve(base, size);
+		fadump_memblock_reserve(base, size);
 		printk(KERN_INFO "Reserved %ldMB of memory at %ldMB "
 				"for saving crash dump\n",
 				(unsigned long)(size >> 20),



More information about the Linuxppc-dev mailing list