(2012/06/23 0:36), Dave Anderson wrote:
----- Original Message -----
OK, doing it that way looks reasonable, and safely segregated to PPC only.
Just two more suggestions -- first, please do me a favor by running
"make warn" prior to posting a patch, and fix these:
$ make warn
TARGET: X86_64
CRASH: 6.0.8rc15
GDB: 7.3.1
cc -c -g -DX86_64 -DGDB_7_3_1 build_data.c -Wall -O2 -Wstrict-prototypes
-Wmissing-prototypes -fstack-protector
cc -c -g -DX86_64 -DGDB_7_3_1 ppc.c -Wall -O2 -Wstrict-prototypes
-Wmissing-prototypes -fstack-protector
cc -c -g -DX86_64 -DGDB_7_3_1 netdump.c -Wall -O2 -Wstrict-prototypes
-Wmissing-prototypes -fstack-protector
netdump.c: In function 'get_netdump_regs_ppc':
netdump.c:2603: warning: pointer targets in passing argument 2 of
'relocate_nt_prstatus_percpu_ppc' differ in signedness
cc -c -g -DX86_64 -DGDB_7_3_1 diskdump.c -Wall -O2 -Wstrict-prototypes
-Wmissing-prototypes -fstack-protector
diskdump.c:1061: warning: no previous prototype for
‘relocate_nt_prstatus_percpu_ppc’
diskdump.c: In function 'get_diskdump_regs_ppc':
diskdump.c:1103: warning: pointer targets in passing argument 2 of
'relocate_nt_prstatus_percpu_ppc' differ in signedness
...
Thanks for your checking out. I shuold use unit * for argument 2.
Secondly, since your new relocate_nt_prstatus_percpu_ppc() and
verify_crash_note_in_kernel_ppc() functions are used for both
kdump ELF and compressed kdump formats, and since they are
PPC-specific, can you just move the two functions into ppc.c?
All that should require is to #include elf.h.
Make sense.
I move them into ppc.c, then function calls in diskdump.c and netdump.c
are wrapped with "if defined (PPC)" so that those lines will be invalid when
other arch is build (x86_64 build was no problem).
I remake and attach patch.
Thanks,
Toshi
Thanks,
Dave
--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility
Date: Thu, 21 Jun 2012 10:39:45 +0900
Subject: [PATCH] ppc: fix up back trace for panic or active tasks problem
When dump file is not contained enough NT_PRSTATUS notes for all online cpus,
ppc diskdump and netdump can not do correct "bt".
Relocate NT_PRSTATUS instances into corresponding cpu maps.
This can do only once when first "bt" command is required.
I couldn't found out good entry point for this while initialization time.
Signed-off-by: Toshikazu Nakayama <[email protected]>
---
defs.h | 1 +
diskdump.c | 7 ++++-
netdump.c | 4 +++
ppc.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 89 insertions(+), 1 deletions(-)
diff --git a/defs.h b/defs.h
index 2145312..09e1bed 100755
--- a/defs.h
+++ b/defs.h
@@ -4746,6 +4746,7 @@ void ppc64_dump_machdep_table(ulong);
#ifdef PPC
void ppc_init(int);
void ppc_dump_machdep_table(ulong);
+void ppc_relocate_nt_prstatus_percpu(void **, uint *);
#define display_idt_table() \
error(FATAL, "-d option is not applicable to PowerPC architecture\n")
#define KSYMS_START (0x1)
diff --git a/diskdump.c b/diskdump.c
index e3f04e8..79dc131 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1018,6 +1018,11 @@ get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
Elf32_Nhdr *note;
int len;
+#if defined (PPC)
+ if (KDUMP_CMPRS_VALID())
+ ppc_relocate_nt_prstatus_percpu(dd->nt_prstatus_percpu,
+ &dd->num_prstatus_notes);
+#endif
if (KDUMP_CMPRS_VALID() &&
(bt->task == tt->panic_task ||
(is_task_active(bt->task) && dd->num_prstatus_notes > 1))) {
@@ -1030,7 +1035,7 @@ get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
"panic" : "active", bt->task);
len = sizeof(Elf32_Nhdr);
len = roundup(len + note->n_namesz, 4);
- bt->machdep = (void *)((char *)note + len +
+ bt->machdep = (void *)((char *)note + len +
MEMBER_OFFSET("elf_prstatus", "pr_reg"));
}
diff --git a/netdump.c b/netdump.c
index 51bbc35..faed2ec 100644
--- a/netdump.c
+++ b/netdump.c
@@ -2595,6 +2595,10 @@ get_netdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
Elf32_Nhdr *note;
size_t len;
+#if defined (PPC)
+ ppc_relocate_nt_prstatus_percpu(nd->nt_prstatus_percpu,
+ &nd->num_prstatus_notes);
+#endif
if ((bt->task == tt->panic_task) ||
(is_task_active(bt->task) && nd->num_prstatus_notes > 1)) {
/*
diff --git a/ppc.c b/ppc.c
index bc5f201..90fe246 100755
--- a/ppc.c
+++ b/ppc.c
@@ -16,6 +16,7 @@
*/
#ifdef PPC
#include "defs.h"
+#include <elf.h>
#define MAX_PLATFORM_LEN 32 /* length for platform string */
@@ -414,6 +415,8 @@ ppc_init(int when)
symbol_exists("hardirq_ctx"))
STRUCT_SIZE_INIT(irq_ctx, "hardirq_ctx");
+ STRUCT_SIZE_INIT(note_buf, "note_buf_t");
+ STRUCT_SIZE_INIT(elf_prstatus, "elf_prstatus");
break;
case POST_INIT:
@@ -1932,4 +1935,79 @@ try_closest:
}
}
}
+
+/*
+ * Try to relocate NT_PRSTATUS notes according by in kernel crash_notes.
+ * Function is only called from ppc's get_regs.
+ */
+static int
+verify_crash_note_in_kernel(int cpu)
+{
+ int ret;
+ Elf32_Nhdr *note32;
+ ulong crash_notes_ptr;
+ char *buf, *name;
+
+ ret = TRUE;
+ if (!readmem(symbol_value("crash_notes"), KVADDR, &crash_notes_ptr,
+ sizeof(ulong), "crash_notes", QUIET|RETURN_ON_ERROR) ||
+ !crash_notes_ptr)
+ goto out;
+
+ buf = GETBUF(SIZE(note_buf));
+ if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF))
+ crash_notes_ptr += kt->__per_cpu_offset[cpu];
+ if (!readmem(crash_notes_ptr, KVADDR, buf, SIZE(note_buf),
+ "cpu crash_notes", QUIET|RETURN_ON_ERROR))
+ goto freebuf;
+
+ note32 = (Elf32_Nhdr *)buf;
+ name = (char *)(note32 + 1);
+ if (note32->n_type != NT_PRSTATUS ||
+ note32->n_namesz != strlen("CORE") + 1 ||
+ strncmp(name, "CORE", note32->n_namesz) ||
+ note32->n_descsz != SIZE(elf_prstatus))
+ ret = FALSE;
+freebuf:
+ FREEBUF(buf);
+out:
+ return ret;
+}
+
+void
+ppc_relocate_nt_prstatus_percpu(void **nt_prstatus_percpu,
+ uint *num_prstatus_notes)
+{
+ static int relocated = FALSE;
+ void **nt_ptr;
+ int i, j, nrcpus;
+ size_t size;
+
+ /* relocation is possible only once */
+ if (relocated == TRUE)
+ return;
+ relocated = TRUE;
+ if (!symbol_exists("crash_notes") ||
+ !VALID_STRUCT(note_buf) || !VALID_STRUCT(elf_prstatus))
+ return;
+
+ size = NR_CPUS * sizeof(void *);
+ nt_ptr = (void **)GETBUF(size);
+ BCOPY(nt_prstatus_percpu, nt_ptr, size);
+ BZERO(nt_prstatus_percpu, size);
+
+ *num_prstatus_notes = 0;
+ nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS);
+ for (i = 0, j = 0; i < nrcpus; i++) {
+ if (!in_cpu_map(ONLINE, i))
+ continue;
+ if (verify_crash_note_in_kernel(i))
+ nt_prstatus_percpu[i] = nt_ptr[j++];
+ else if (CRASHDEBUG(1))
+ error(WARNING, "cpu#%d: not saved crash_notes\n", i);
+ /* num_prstatus_notes is always equal to online cpus in ppc */
+ (*num_prstatus_notes)++;
+ }
+ FREEBUF(nt_ptr);
+}
#endif /* PPC */
--
1.7.0.4
--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility