* [PATCH] kexec/ppc: cleanup crash regions creation
@ 2014-03-07 7:40 Nikita Yushchenko
2014-03-21 10:58 ` Nikita Yushchenko
0 siblings, 1 reply; 3+ messages in thread
From: Nikita Yushchenko @ 2014-03-07 7:40 UTC (permalink / raw)
To: kexec; +Cc: yadviga, nyushchenko, lugovskoy
Move filling crash_memory_range table entries into a separate routine,
which saves quite a few lines of code.
In this routine, if range spawns over lowmem-highmem border, split range
into two. This is needed to get proper virtual address for lowmem part.
Similar thing is already done for x86. Credits to Yadviga Grigorieva
<yadviga@dev.rtsoft.ru> for tracking down this issue for ppc.
Also this patch makes excluding crash kernel regoin a bit shorter, and
removes unused variable to get rid of compiler warning.
Signed-off-by: Nikita Yushchenko <nyushchenko@dev.rtsoft.ru>
---
kexec/arch/ppc/crashdump-powerpc.c | 108 +++++++++++++++++-------------------
1 files changed, 51 insertions(+), 57 deletions(-)
diff --git a/kexec/arch/ppc/crashdump-powerpc.c b/kexec/arch/ppc/crashdump-powerpc.c
index c06d310..3dc35eb 100644
--- a/kexec/arch/ppc/crashdump-powerpc.c
+++ b/kexec/arch/ppc/crashdump-powerpc.c
@@ -41,6 +41,7 @@ lowmem_limit: MAXMEM,
* A separate program header is created for backup region
*/
static struct memory_range *crash_memory_range;
+static int crash_nr_memory_ranges;
/* Define a variable to replace the CRASH_MAX_MEMORY_RANGES macro */
static int crash_max_memory_ranges;
@@ -51,6 +52,29 @@ static int crash_max_memory_ranges;
*/
mem_rgns_t usablemem_rgns = {0, NULL};
+/* Append a segment to crash_memory_range, splitting it into two if
+ * it contains both lowmem and highmem */
+static void add_crash_memory_range(unsigned long long start,
+ unsigned long long end)
+{
+#ifndef CONFIG_PPC64
+ if (start < elf_info32.lowmem_limit && end > elf_info32.lowmem_limit) {
+ add_crash_memory_range(start, elf_info32.lowmem_limit);
+ add_crash_memory_range(elf_info32.lowmem_limit, end);
+ return;
+ }
+#endif
+
+ if (crash_nr_memory_ranges < crash_max_memory_ranges) {
+ crash_memory_range[crash_nr_memory_ranges].start = start;
+ crash_memory_range[crash_nr_memory_ranges].end = end;
+ crash_memory_range[crash_nr_memory_ranges].type = RANGE_RAM;
+ }
+
+ crash_nr_memory_ranges++;
+}
+
+
/* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to
* create Elf headers. Keeping it separate from get_memory_ranges() as
* requirements are different in the case of normal kexec and crashdumps.
@@ -65,13 +89,12 @@ mem_rgns_t usablemem_rgns = {0, NULL};
static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
{
- int memory_ranges = 0;
char device_tree[256] = "/proc/device-tree/";
char fname[256];
DIR *dir, *dmem;
int fd;
struct dirent *dentry, *mentry;
- int i, n, crash_rng_len = 0;
+ int n, crash_rng_len = 0;
unsigned long long start, end, cstart, cend;
crash_max_memory_ranges = max_memory_ranges + 6;
@@ -83,13 +106,11 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
return -1;
}
memset(crash_memory_range, 0, crash_rng_len);
+ crash_nr_memory_ranges = 0;
#ifndef CONFIG_BOOKE
/* create a separate program header for the backup region */
- crash_memory_range[0].start = BACKUP_SRC_START;
- crash_memory_range[0].end = BACKUP_SRC_END + 1;
- crash_memory_range[0].type = RANGE_RAM;
- memory_ranges++;
+ add_crash_memory_range(BACKUP_SRC_START, BACKUP_SRC_END + 1);
#endif
dir = opendir(device_tree);
@@ -128,70 +149,37 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
closedir(dir);
goto err;
}
- if (memory_ranges >= (max_memory_ranges + 1)) {
- /* No space to insert another element. */
- fprintf(stderr,
- "Error: Number of crash memory ranges"
- " excedeed the max limit\n");
- goto err;
- }
#ifndef CONFIG_BOOKE
if (start == 0 && end >= (BACKUP_SRC_END + 1))
start = BACKUP_SRC_END + 1;
#endif
- cstart = crash_base;
- cend = crash_base + crash_size;
/*
* 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
- = start;
- crash_memory_range[memory_ranges].end
- = cstart;
- crash_memory_range[memory_ranges].type
- = RANGE_RAM;
- memory_ranges++;
- crash_memory_range[memory_ranges].start
- = cend;
- crash_memory_range[memory_ranges].end
- = end;
- crash_memory_range[memory_ranges].type
- = RANGE_RAM;
- memory_ranges++;
- } else if (start < cstart) {
- crash_memory_range[memory_ranges].start
- = start;
- crash_memory_range[memory_ranges].end
- = cstart;
- crash_memory_range[memory_ranges].type
- = RANGE_RAM;
- memory_ranges++;
- } else if (end > cend) {
- crash_memory_range[memory_ranges].start
- = cend;
- crash_memory_range[memory_ranges].end
- = end;
- crash_memory_range[memory_ranges].type
- = RANGE_RAM;
- memory_ranges++;
- }
- } else {
- crash_memory_range[memory_ranges].start = start;
- crash_memory_range[memory_ranges].end = end;
- crash_memory_range[memory_ranges].type
- = RANGE_RAM;
- memory_ranges++;
+
+ /*
+ * Exclure region used by crash kernel
+ */
+ cstart = crash_base;
+ cend = crash_base + crash_size;
+
+ if (cstart >= end || cend <= start)
+ add_crash_memory_range(start, end);
+ else {
+ if (start < cstart)
+ add_crash_memory_range(start, cstart);
+ if (cend < end)
+ add_crash_memory_range(cend, end);
}
}
closedir(dmem);
@@ -210,12 +198,18 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
cstart = crash_base;
if (cend > crash_base + crash_size)
cend = crash_base + crash_size;
- crash_memory_range[memory_ranges].start = cstart;
- crash_memory_range[memory_ranges++].end = cend;
+ add_crash_memory_range(cstart, cend);
+ }
+
+ if (crash_nr_memory_ranges >= crash_max_memory_ranges) {
+ fprintf(stderr,
+ "Error: Number of crash memory ranges"
+ " excedeed the max limit\n");
+ goto err;
}
*range = crash_memory_range;
- *ranges = memory_ranges;
+ *ranges = crash_nr_memory_ranges;
int j;
dbgprintf("CRASH MEMORY RANGES\n");
--
1.7.0.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] kexec/ppc: cleanup crash regions creation
2014-03-07 7:40 [PATCH] kexec/ppc: cleanup crash regions creation Nikita Yushchenko
@ 2014-03-21 10:58 ` Nikita Yushchenko
2014-04-09 23:22 ` Simon Horman
0 siblings, 1 reply; 3+ messages in thread
From: Nikita Yushchenko @ 2014-03-21 10:58 UTC (permalink / raw)
To: kexec; +Cc: yadviga, lugovskoy
> Move filling crash_memory_range table entries into a separate routine,
> which saves quite a few lines of code.
>
> In this routine, if range spawns over lowmem-highmem border, split range
> into two. This is needed to get proper virtual address for lowmem part.
> Similar thing is already done for x86. Credits to Yadviga Grigorieva
> <yadviga@dev.rtsoft.ru> for tracking down this issue for ppc.
>
> Also this patch makes excluding crash kernel region a bit shorter, and
> removes unused variable to get rid of compiler warning.
>
> Signed-off-by: Nikita Yushchenko <nyushchenko@dev.rtsoft.ru>
> ---
> kexec/arch/ppc/crashdump-powerpc.c | 108 +++++++++++++++++-------------------
> 1 files changed, 51 insertions(+), 57 deletions(-)
Hi
Any followup on this?
Without this patch, vmcore files extracted with kdump is not very useful with gdb:
root@freescale-p2020ds:~# gdb ./vmlinux /mnt/vmcore
--command=/usr/share/gdb/macros/gdb-kdump-helpers/gdbinit_commit
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "powerpc-montavista-linux-gnuspe".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/root/vmlinux...done.
[New LWP 2720]
#0 0xc035ae4c in sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:138
138 drivers/tty/sysrq.c: No such file or directory.
(gdb) bt
#0 0xc035ae4c in sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:138
#1 0xc035b6dc in __handle_sysrq (key=99,
key@entry=<error reading variable: Cannot access memory at address
0xed679ed4>, check_mask=<optimized out>) at drivers/tty/sysrq.c:533
(gdb) ps
PID tty CMD
Cannot access memory at address 0xef85858c
(gdb)
With this patch, things are much better:
(gdb) bt
#0 0xc033c1e0 in sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:138
#1 0xc033ca68 in __handle_sysrq (key=99, check_mask=check_mask@entry=false)
at drivers/tty/sysrq.c:533
#2 0xc033cb24 in write_sysrq_trigger (file=<optimized out>, buf=<optimized
out>,
count=2, ppos=<optimized out>) at drivers/tty/sysrq.c:1030
#3 0xc0192654 in proc_reg_write (file=<optimized out>, buf=<optimized out>,
count=<optimized out>, ppos=<optimized out>) at fs/proc/inode.c:224
#4 0xc0135dd4 in vfs_write (file=file@entry=0xcfa78240,
buf=buf@entry=0x1011b408 <Address 0x1011b408 out of bounds>,
count=count@entry=2,
pos=pos@entry=0xcf71ff18) at fs/read_write.c:446
#5 0xc0136258 in SYSC_write (count=2,
buf=0x1011b408 <Address 0x1011b408 out of bounds>, fd=<optimized out>)
at fs/read_write.c:494
#6 SyS_write (fd=<optimized out>, buf=269595656, count=2) at
fs/read_write.c:487
#7 0xc000ed08 in syscall_dotrace_cont () at arch/powerpc/kernel/entry_32.S:385
Backtrace stopped: frame did not save the PC
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] kexec/ppc: cleanup crash regions creation
2014-03-21 10:58 ` Nikita Yushchenko
@ 2014-04-09 23:22 ` Simon Horman
0 siblings, 0 replies; 3+ messages in thread
From: Simon Horman @ 2014-04-09 23:22 UTC (permalink / raw)
To: Nikita Yushchenko; +Cc: yadviga, lugovskoy, kexec
On Fri, Mar 21, 2014 at 02:58:57PM +0400, Nikita Yushchenko wrote:
> > Move filling crash_memory_range table entries into a separate routine,
> > which saves quite a few lines of code.
> >
> > In this routine, if range spawns over lowmem-highmem border, split range
> > into two. This is needed to get proper virtual address for lowmem part.
> > Similar thing is already done for x86. Credits to Yadviga Grigorieva
> > <yadviga@dev.rtsoft.ru> for tracking down this issue for ppc.
> >
> > Also this patch makes excluding crash kernel region a bit shorter, and
> > removes unused variable to get rid of compiler warning.
> >
> > Signed-off-by: Nikita Yushchenko <nyushchenko@dev.rtsoft.ru>
> > ---
> > kexec/arch/ppc/crashdump-powerpc.c | 108 +++++++++++++++++-------------------
> > 1 files changed, 51 insertions(+), 57 deletions(-)
>
> Hi
>
> Any followup on this?
>
> Without this patch, vmcore files extracted with kdump is not very useful with gdb:
Apologies for the delay, I have applied this patch.
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-04-09 23:23 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-07 7:40 [PATCH] kexec/ppc: cleanup crash regions creation Nikita Yushchenko
2014-03-21 10:58 ` Nikita Yushchenko
2014-04-09 23:22 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox