diff options
author | Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> | 2013-02-12 16:17:37 +0530 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2013-03-05 11:11:07 +0900 |
commit | 0d4ff47c810bd13b1160fade55a803706021840c (patch) | |
tree | a6f4f560d3b607d7b42fddac6ccf2a800980db5c | |
parent | a69f5b5a432fc0abf6655a8b0bc667a900511f7d (diff) | |
download | kexec-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.c | 11 | ||||
-rw-r--r-- | kexec/arch/ppc64/crashdump-ppc64.h | 1 | ||||
-rw-r--r-- | kexec/arch/ppc64/kexec-ppc64.c | 27 |
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); |