Skip to contentSkip to conversation

kexec: Limit the crash memory ranges according to first kernel's memory limit.

PATCH In review Mahesh J Salgaonkar 2 participants 4 messages Feb 12, 2013 – Mar 5, 2013

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v2 cover kexec: Limit the crash memory ranges according to first kernel's memory limit.

So far powerpc kernel never exported memory limit information which is reflected by mem= kernel cmdline option. Hence, kexec-tools always use to build ELF header for entire system RAM generating a dump bigger than the actual memory used by the first kernel.

The following upstream kernel commits now exports memory limit information through /proc/device-tree file:
4bc77a5ed - powerpc: Export memory limit via device tree a84fcd468 - powerpc: Change memory_limit from phys_addr_t to unsigned
long long

This patch series now reads the memory limit information from device-tree file if present and limits the crash memory ranges accordingly.

Tested these patches on ppc32(ppc440) and ppc64 with a kernel patch by Suzuki.

Changes in v2:
- Fixed few formatting and coding style issues.
- Fixed error handling path and possible buffer overflow issue in patch 1/2.
- Fixed an issue where an additional PT_LOAD section, representing zero size memory segment (with start address == memory_limit), was getting added to ELF section.

---

Mahesh Salgaonkar (2):
kexec: Respect memory limit while building crash memory ranges on ppc32.
kexec: Respect memory limit while building crash memory ranges on ppc64

 kexec/arch/ppc/crashdump-powerpc.c |   14 ++++++++--
 kexec/arch/ppc/crashdump-powerpc.h |    1 +
 kexec/arch/ppc/kexec-ppc.c         |   51 ++++++++++++++++++++++++++++++++++++
 kexec/arch/ppc64/crashdump-ppc64.c |   11 +++++++-
 kexec/arch/ppc64/crashdump-ppc64.h |    1 +
 kexec/arch/ppc64/kexec-ppc64.c     |   27 +++++++++++++++++++
 6 files changed, 101 insertions(+), 4 deletions(-)
Signature · 7 lines
-Mahesh


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#1 lore raw

PATCH v2 1/2 kexec: Respect memory limit while building crash memory ranges on ppc32.

From: Mahesh Salgaonkar <[email protected]>

So far powerpc kernel never exported memory limit information which is reflected by mem= kernel cmdline option. Hence, kexec-tools always used to build ELF header for entire system RAM generating a dump bigger than the actual memory used by the first kernel.

This patch now reads the memory limit information from device-tree file and limits the crash memory ranges accordingly.

Suzuki tested this patch on ppc32(ppc440) with a kernel patch by Suzuki.

The following are the upstream kernel commits that exports memory limit information through /proc/device-tree file:
4bc77a5ed - powerpc: Export memory limit via device tree a84fcd468 - powerpc: Change memory_limit from phys_addr_t to unsigned
long long

---
 kexec/arch/ppc/crashdump-powerpc.c |   14 ++++++++--
 kexec/arch/ppc/crashdump-powerpc.h |    1 +
 kexec/arch/ppc/kexec-ppc.c         |   51 ++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 3 deletions(-)
kexec/arch/ppc/crashdump-powerpc.c +11 -3
index 4c8c75d..d367643 100644
@@ -132,8 +132,9 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
 				goto err;
 			}
 			n = read_memory_region_limits(fd, &start, &end);
+			/* We are done with fd, close it. */
+			close(fd);
 			if (n != 0) {
-				close(fd);
 				closedir(dmem);
 				closedir(dir);
 				goto err;
@@ -153,8 +154,16 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
 			cstart = crash_base;
 			cend = crash_base + crash_size;
 			/*
-			 * Exclude the region that lies within crashkernel
+			 * Exclude the region that lies within crashkernel.
+			 * If memory limit is set then exclude memory region
+			 * above it.
 			 */
+			if (memory_limit) {
+				if (start >= memory_limit)
+					continue;
+				if (end > memory_limit)
+					end = memory_limit;
+			}
 			if (cstart < end && cend > start) {
 				if (start < cstart && end > cend) {
 					crash_memory_range[memory_ranges].start
@@ -195,7 +204,6 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
 					= RANGE_RAM;
 				memory_ranges++;
 			}
-			close(fd);
 		}
 		closedir(dmem);
 	}
kexec/arch/ppc/crashdump-powerpc.h +1 -0
index a377146..84a73aa 100644
@@ -42,5 +42,6 @@ extern unsigned long long crash_base;
 extern unsigned long long crash_size;
 extern unsigned int rtas_base;
 extern unsigned int rtas_size;
+extern uint64_t memory_limit;
 
 #endif /* CRASHDUMP_POWERPC_H */
kexec/arch/ppc/kexec-ppc.c +51 -0

69 lines not on this page · raw message

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#2 lore raw

PATCH v2 2/2 kexec: Respect memory limit while building crash memory ranges on ppc64

In reply to Mahesh J Salgaonkar

From: Mahesh Salgaonkar <[email protected]>

Fix it on ppc64 also. This patch now reads the memory limit information from device-tree file and limits the crash memory ranges accordingly.

Tested this patch on ppc64 with upstream kernel version 3.8.0-rc4

---
 kexec/arch/ppc64/crashdump-ppc64.c |   11 ++++++++++-
 kexec/arch/ppc64/crashdump-ppc64.h |    1 +
 kexec/arch/ppc64/kexec-ppc64.c     |   27 +++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)
kexec/arch/ppc64/crashdump-ppc64.c +10 -1
index 30ef443..b8a63bd 100644
@@ -84,10 +84,19 @@ static unsigned long long cstart, cend;
 static int memory_ranges;
 
 /*
- * Exclude the region that lies within crashkernel
+ * Exclude the region that lies within crashkernel and above the memory
+ * limit which is reflected by mem= kernel option.
  */
 static void exclude_crash_region(uint64_t start, uint64_t end)
 {
+	/* If memory_limit is set then exclude the memory region above it. */
+	if (memory_limit) {
+		if (start >= memory_limit)
+			return;
+		if (end > memory_limit)
+			end = memory_limit;
+	}
+
 	if (cstart < end && cend > start) {
 		if (start < cstart && end > cend) {
 			crash_memory_range[memory_ranges].start = start;
kexec/arch/ppc64/crashdump-ppc64.h +1 -0
index be02213..739c61f 100644
@@ -27,6 +27,7 @@ void add_usable_mem_rgns(unsigned long long base, unsigned long long size);
 
 extern uint64_t crash_base;
 extern uint64_t crash_size;
+extern uint64_t memory_limit;
 extern unsigned int rtas_base;
 extern unsigned int rtas_size;
 
kexec/arch/ppc64/kexec-ppc64.c +27 -0
index 2f12907..389741a 100644
@@ -39,6 +39,7 @@ static struct memory_range *memory_range = NULL;
 static struct memory_range *base_memory_range = NULL;
 static uint64_t rmo_top;
 uint64_t memory_max = 0;
+uint64_t memory_limit;
 static int nr_memory_ranges, nr_exclude_ranges;
 uint64_t crash_base, crash_size;
 unsigned int rtas_base, rtas_size;
@@ -408,6 +409,32 @@ static int get_devtree_details(unsigned long kexec_flags)
 				add_usable_mem_rgns(0, crash_base + crash_size);
 				reserve(KDUMP_BACKUP_LIMIT, crash_base-KDUMP_BACKUP_LIMIT);
 			}
+			/*
+			 * Read the first kernel's memory limit.
+			 * If the first kernel is booted with mem= option then
+			 * it would export "linux,memory-limit" file
+			 * reflecting value for the same.
+			 */
+			memset(fname, 0, sizeof(fname));
+			strcpy(fname, device_tree);
+			strcat(fname, dentry->d_name);
+			strcat(fname, "/linux,memory-limit");
+			if ((file = fopen(fname, "r")) == NULL) {
+				if (errno != ENOENT) {
+					perror(fname);
+					goto error_opencdir;
+				}
+				errno = 0;
+				/*
+				 * File not present.
+				 * fall through. On older kernel this file
+				 * is not present.
+				 */
+			} else if (fread(&memory_limit, sizeof(uint64_t), 1,
+								file) != 1) {
+				perror(fname);
+				goto error_openfile;
+			}
 
 			memset(fname, 0, sizeof(fname));
 			strcpy(fname, device_tree);

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#3 lore raw
In reply to Mahesh J Salgaonkar
Quoted 23 lines · Mahesh J Salgaonkar

So far powerpc kernel never exported memory limit information which is reflected by mem= kernel cmdline option. Hence, kexec-tools always use to build ELF header for entire system RAM generating a dump bigger than the actual memory used by the first kernel.

The following upstream kernel commits now exports memory limit information through /proc/device-tree file:
4bc77a5ed - powerpc: Export memory limit via device tree a84fcd468 - powerpc: Change memory_limit from phys_addr_t to unsigned
long long

This patch series now reads the memory limit information from device-tree file if present and limits the crash memory ranges accordingly.

Tested these patches on ppc32(ppc440) and ppc64 with a kernel patch by Suzuki.

Changes in v2:
- Fixed few formatting and coding style issues.
- Fixed error handling path and possible buffer overflow issue in patch 1/2.
- Fixed an issue where an additional PT_LOAD section, representing zero size memory segment (with start address == memory_limit), was getting added to ELF section.

Quoted 2 lines

Thanks, both patches applied.

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec