[PATCH] Reserve crashkernel memory region
Mohan Kumar M
mohan at in.ibm.com
Mon Apr 24 16:10:15 EST 2006
Hi,
Now kexec'ed kernel in a PPC64 machine does not reserve memory for crashkernel region. So kexec'ed kernel can not load kdump kernel reliably.
Attached kexec-tools patch reserves memory for kdump kernel by adding an entry in the reserve memory table. So while kexec'ed kernel is booting, it reserves memory for crashkernel region.
Regards,
Mohan.
-------------- next part --------------
In PPC64, kexec'ed kernel does not reserve memory for crashkernel. So
kexec'ed kernel can not load kdump kernel reliably.
reserve-crashkernel-mem patch adds a reserve entry for crashkernel to the
reserve memory list, so that kexec'ed kernel reserves memory for kdump kernel.
This is done when user passes --append="crashkernel=X at Y" parameter to
kexec command. If user does not pass crashkernel option, memory is not
reserved for kdump kernel.
Signed-off-by: Mohan <mohan at in.ibm.com>
---
kexec-tools-1.101-kdump9/kexec/arch/ppc64/fs2dt.c | 135 ++++++++++++----
kexec-tools-1.101-kdump9/kexec/arch/ppc64/kexec-ppc64.h | 2
2 files changed, 107 insertions(+), 30 deletions(-)
diff -puN kexec-tools-1.101-kdump9/kexec/arch/ppc64/fs2dt.c~reserve-crashkernel kexec-tools-1.101-kdump9/kexec/arch/ppc64/fs2dt.c
--- patch/kexec-tools-1.101-kdump9/kexec/arch/ppc64/fs2dt.c~reserve-crashkernel 2006-04-19 18:49:06.000000000 +0530
+++ patch-mohan/kexec-tools-1.101-kdump9/kexec/arch/ppc64/fs2dt.c 2006-04-19 18:55:48.000000000 +0530
@@ -64,8 +64,7 @@ char propnames[NAMESPACE];
dvt dtstruct[TREEWORDS], *dt;
unsigned long long mem_rsrv[2*MEMRESERVE];
-static int initrd_found = 0;
-static int crash_param = 0;
+static unsigned long crashk_base = 0, crashk_size = 0;
char local_cmdline[COMMAND_LINE_SIZE] = { "" };
dvt *dt_len; /* changed len of modified cmdline in flat device-tree */
extern mem_rgns_t usablemem_rgns;
@@ -191,6 +190,50 @@ void add_usable_mem_property(int fd, int
dt += (rlen + 3)/4;
}
+unsigned long mem_parse(const char *ptr, const char **retptr)
+{
+ unsigned long ret = strtoul(ptr, (char **)retptr,10);
+
+ switch (**retptr) {
+ case 'G':
+ case 'g':
+ ret <<= 30;
+ (*retptr)++;
+ break;
+ case 'M':
+ case 'm':
+ ret <<= 20;
+ (*retptr)++;
+ break;
+ case 'K':
+ case 'k':
+ ret <<= 10;
+ (*retptr)++;
+ break;
+ }
+
+ return ret;
+}
+
+void parse_crash_param(char *param)
+{
+ char *cbase, *csize;
+ param += 12;
+ crashk_size = mem_parse(param, (const char **)&csize);
+
+ if (ALIGN(crashk_size, 0x1000000) != crashk_size)
+ printf("Warning: crashkernel size is not aligned to 16MB\n");
+
+ if (*csize == '@') {
+ csize++;
+ crashk_base = mem_parse(csize, (const char **)&cbase);
+ if (crashk_base != 0x2000000)
+ printf("Warning: PPC64 kdump kernel always runs at "
+ "32 MB\n");
+ }
+ crashk_base = 0x2000000;
+}
+
/* put all properties (files) in the property structure */
void putprops(char *fn, struct dirent **nlist, int numlist)
{
@@ -207,12 +250,6 @@ void putprops(char *fn, struct dirent **
if (lstat(pathname, statbuf))
err(pathname, ERR_STAT);
- if (!crash_param && !strcmp(fn,"linux,crashkernel-base"))
- continue;
-
- if (!crash_param && !strcmp(fn,"linux,crashkernel-size"))
- continue;
-
/*
* This property will be created for each node during kexec
* boot. So, ignore it.
@@ -230,6 +267,13 @@ void putprops(char *fn, struct dirent **
!strcmp(dp->d_name, "linux,initrd-end"))
continue;
+ /* This property will be created/modified later in putnode()
+ * So ignore it.
+ */
+ if (!strcmp(dp->d_name, "linux,crashkernel-base") ||
+ !strcmp(dp->d_name, "linux,crashkernel-size"))
+ continue;
+
if (S_ISREG(statbuf[0].st_mode)) {
int fd, len = statbuf[0].st_size;
@@ -260,7 +304,7 @@ void putprops(char *fn, struct dirent **
param = strstr(local_cmdline,
"crashkernel=");
if (param)
- crash_param = 1;
+ parse_crash_param(param);
param = strstr(local_cmdline, "root=");
}
if (!param) {
@@ -347,35 +391,66 @@ void putnode(void)
putprops(dn, namelist, numlist);
- /* Add initrd entries to the second kernel if first kernel does not
- * have and second kernel needs.
- */
- if (initrd_base && !initrd_found && !strcmp(basename,"/chosen/")) {
+ if (!strcmp(basename,"/chosen/")) {
int len = 8;
unsigned long long initrd_end;
- *dt++ = 3;
- *dt++ = len;
- *dt++ = propnum("linux,initrd-start");
- if ((len >= 8) && ((unsigned long)dt & 0x4))
- dt++;
+ /* Add initrd entries to the second kernel if first
+ * kernel does not have and second kernel needs.
+ */
+ if (initrd_base) {
+ *dt++ = 3;
+ *dt++ = len;
+ *dt++ = propnum("linux,initrd-start");
+
+ if ((len >= 8) && ((unsigned long)dt & 0x4))
+ dt++;
+
+ memcpy(dt,&initrd_base,len);
+ dt += (len + 3)/4;
+
+ len = 8;
+ *dt++ = 3;
+ *dt++ = len;
+ *dt++ = propnum("linux,initrd-end");
+
+ initrd_end = initrd_base + initrd_size;
+ if ((len >= 8) && ((unsigned long)dt & 0x4))
+ dt++;
+
+ memcpy(dt,&initrd_end,len);
+ dt += (len + 3)/4;
+
+ reserve(initrd_base, initrd_size);
+ }
+
+ /* Add crashkernel details to the second kernel if first
+ * kernel does not have and reserve memory for that
+ */
+ if (crashk_base) {
+ *dt++ = 3;
+ *dt++ = len;
+ *dt++ = propnum("linux,crashkernel-base");
- memcpy(dt,&initrd_base,len);
- dt += (len + 3)/4;
+ if ((len >= 8) && ((unsigned long)dt & 0x4))
+ dt++;
- len = 8;
- *dt++ = 3;
- *dt++ = len;
- *dt++ = propnum("linux,initrd-end");
+ memcpy(dt,&crashk_base,len);
+ dt += (len + 3)/4;
- initrd_end = initrd_base + initrd_size;
- if ((len >= 8) && ((unsigned long)dt & 0x4))
- dt++;
+ len = 8;
+ *dt++ = 3;
+ *dt++ = len;
+ *dt++ = propnum("linux,crashkernel-size");
+
+ if ((len >= 8) && ((unsigned long)dt & 0x4))
+ dt++;
- memcpy(dt,&initrd_end,len);
- dt += (len + 3)/4;
+ memcpy(dt,&crashk_size,len);
+ dt += (len + 3)/4;
- reserve(initrd_base, initrd_size);
+ reserve(crashk_base, crashk_size);
+ }
}
for (i=0; i < numlist; i++) {
diff -puN kexec-tools-1.101-kdump9/kexec/arch/ppc64/kexec-ppc64.h~reserve-crashkernel kexec-tools-1.101-kdump9/kexec/arch/ppc64/kexec-ppc64.h
--- patch/kexec-tools-1.101-kdump9/kexec/arch/ppc64/kexec-ppc64.h~reserve-crashkernel 2006-04-19 18:49:54.000000000 +0530
+++ patch-mohan/kexec-tools-1.101-kdump9/kexec/arch/ppc64/kexec-ppc64.h 2006-04-19 18:50:29.000000000 +0530
@@ -7,6 +7,8 @@
#define CORE_TYPE_ELF32 1
#define CORE_TYPE_ELF64 2
+#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
+
int setup_memory_ranges(unsigned long kexec_flags);
int elf_ppc64_probe(const char *buf, off_t len);
_
More information about the Linuxppc-dev
mailing list