summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2013-02-12 16:17:37 +0530
committerSimon Horman <horms@verge.net.au>2013-03-05 11:11:07 +0900
commit0d4ff47c810bd13b1160fade55a803706021840c (patch)
treea6f4f560d3b607d7b42fddac6ccf2a800980db5c
parenta69f5b5a432fc0abf6655a8b0bc667a900511f7d (diff)
downloadkexec-tools-0d4ff47c810bd13b1160fade55a803706021840c.tar.gz
kexec: Respect memory limit while building crash memory ranges on ppc64
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 Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--kexec/arch/ppc64/crashdump-ppc64.c11
-rw-r--r--kexec/arch/ppc64/crashdump-ppc64.h1
-rw-r--r--kexec/arch/ppc64/kexec-ppc64.c27
3 files changed, 38 insertions, 1 deletions
diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c
index 30ef443f..b8a63bda 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -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;
diff --git a/kexec/arch/ppc64/crashdump-ppc64.h b/kexec/arch/ppc64/crashdump-ppc64.h
index be022133..739c61f9 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.h
+++ b/kexec/arch/ppc64/crashdump-ppc64.h
@@ -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;
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
index 2f129079..389741a5 100644
--- a/kexec/arch/ppc64/kexec-ppc64.c
+++ b/kexec/arch/ppc64/kexec-ppc64.c
@@ -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);