Haren Myneni wrote:
Reposting this patch as it did not made to crash mailing list. Dave,
Thanks for adding my different e-mail address to subscriber list.
No problem -- I prefer to keep this list subscriber-only to avoid the spam
you see on other lists...
Dave,
Attaching a patch which contains ppc64 specific changes to read kdump
vmcore. As we are saving pt_regs for all cpus, it reads them from vmcore
instead of looking for specific symbols, used for PPC64 netdump/diskdump
vmcore. Also, prints regs before any active backtrace. Whereas for
netdump vmcore, regs will be displayed anyway as part of exception frame
since the 'bt' command displays from the top frame.
Verified with "Make Warn"
Please let me know if you have any comments.
This patch looks good. No comment... ;-)
As Badari mentioned, when the sparsemem is enabled, pg_dat->node_mem_map
member does not exists. mem_map for each node is scattered across
multiple sections and is not contiguous. Therefore, some detailed
changes are needed. Until we fix this issue, can we include some hack
so that users can use other commands for vmcore analysis.
The fix will be:
if (MEMBER_EXISTS("pglist_data", "node_mem_map"))
readmem(pgdat+OFFSET(pglist_data_node_mem_map), KVADDR,
&node_mem_map, sizeof(ulong),
"node_mem_map", FAULT_ON_ERROR);
[I noticed your response to Badari's posting. Since the sparsemem is
effected only for powerpc at this point, we thought, user can use the
limited functionality with the above change. (Ex: bt) until we have the
complete fix. At least we will be having crash tool available for kdump
vmore on ppc64. The sparsemem issue will be fixed soon. Ok, please
ignore this if you prefer to wait for the complete fix]
I was tinkering around with this by simulating the bogus setting of
"node_mem_map" above, and I'm surprised that you can get as much
functionality as crash does give you. Most people probably wouldn't even
notice. Anyway, I was about to change my mind, and put the EXISTS
check in for now -- but along with a non-fatal error message that would be
annoying enough for you guys to whip up a real fix. I'll still do that,
unless by "fixed soon", you mean in a day or two?
Dave
Thanks
Haren
------------------------------------------------------------------------------------------------------------------------
diff -Naurp crash-4.0-2.20.orig/netdump.c crash-4.0-2.20/netdump.c
--- crash-4.0-2.20.orig/netdump.c 2006-02-11 16:50:28.000000000 -0800
+++ crash-4.0-2.20/netdump.c 2006-02-11 16:50:58.000000000 -0800
@@ -1680,7 +1680,13 @@ get_netdump_regs_ppc64(struct bt_info *b
Elf64_Nhdr *note;
size_t len;
- if (bt->task == tt->panic_task) {
+ if ((bt->task == tt->panic_task) ||
+ (is_task_active(bt->task) && nd->num_prstatus_notes >
1)) {
+ /*
+ * Registers are saved during the dump process for the
+ * panic task. Whereas in kdump, regs are captured for all
+ * CPUs if they responded to an IPI.
+ */
if (nd->num_prstatus_notes > 1)
note = (Elf64_Nhdr *)
nd->nt_prstatus_percpu[bt->tc->processor];
diff -Naurp crash-4.0-2.20.orig/ppc64.c crash-4.0-2.20/ppc64.c
--- crash-4.0-2.20.orig/ppc64.c 2006-02-11 16:50:32.000000000 -0800
+++ crash-4.0-2.20/ppc64.c 2006-02-13 16:10:56.000000000 -0800
@@ -1420,20 +1420,11 @@ ppc64_check_eframe(struct ppc64_pt_regs
return NULL;
}
-/*
- * Print exception frame information for ppc64
- */
static void
-ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
- struct bt_info *bt)
+ppc64_print_regs(struct ppc64_pt_regs *regs)
{
int i;
- if (BT_REFERENCE_CHECK(bt))
- return;
-
- fprintf(fp, " %s [%lx] exception frame:", efrm_str, regs->trap);
-
/* print out the gprs... */
for(i=0; i<32; i++) {
if(!(i % 3))
@@ -1465,9 +1456,66 @@ ppc64_print_eframe(char *efrm_str, struc
fprintf(fp, "DAR: %016lx\n", regs->dar);
fprintf(fp, " DSISR: %016lx ", regs->dsisr);
fprintf(fp, " Syscall Result: %016lx\n", regs->result);
+}
+
+/*
+ * Print the exception frame information
+ */
+static void
+ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
+ struct bt_info *bt)
+{
+ if (BT_REFERENCE_CHECK(bt))
+ return;
+
+ fprintf(fp, " %s [%lx] exception frame:", efrm_str, regs->trap);
+ ppc64_print_regs(regs);
fprintf(fp, "\n");
}
+/*
+ * get SP and IP from the saved ptregs.
+ */
+static int
+ppc64_kdump_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+{
+ struct ppc64_pt_regs *pt_regs;
+ unsigned long unip;
+
+ pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
+ if (!pt_regs->gpr[1]) {
+ /*
+ * Not collected regs. May be the corresponding CPU not
+ * responded to an IPI.
+ */
+ fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n",
+ bt_in->task);
+ return FALSE;
+ }
+ *ksp = pt_regs->gpr[1];
+ readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
+ FAULT_ON_ERROR);
+ *nip = unip;
+
+ if (bt_in->flags &&
+ ((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)))
+ return TRUE;
+
+ /*
+ * Print the collected regs for the active task
+ */
+ ppc64_print_regs(pt_regs);
+
+ fprintf(fp, " NIP [%016lx] %s\n", pt_regs->nip,
+ closest_symbol(pt_regs->nip));
+ if (unip != pt_regs->link)
+ fprintf(fp, " LR [%016lx] %s\n", pt_regs->link,
+ closest_symbol(pt_regs->link));
+
+ fprintf(fp, "\n");
+
+ return TRUE;
+}
/*
* Get the starting point for the active cpus in a diskdump/netdump.
@@ -1485,12 +1533,18 @@ ppc64_get_dumpfile_stack_frame(struct bt
ulong ur_ksp = 0;
int check_hardirq, check_softirq;
int check_intrstack = TRUE;
+ struct ppc64_pt_regs *pt_regs;
+
+ /*
+ * For the kdump vmcore, Use SP and IP values that are saved in ptregs.
+ */
+ if (pc->flags && KDUMP)
+ return ppc64_kdump_stack_frame(bt_in, nip, ksp);
bt = &bt_local;
BCOPY(bt_in, bt, sizeof(struct bt_info));
ms = machdep->machspec;
ur_nip = ur_ksp = 0;
- struct ppc64_pt_regs *pt_regs;
panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
------------------------------------------------------------------------------------------------------------------------
--
Crash-utility mailing list
Crash-utility(a)redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility