ppc: fix backtrace problem when NT_PRSTATUS was not saved

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dave,

I've reworked patch about ppc "bt" problem discussed in
 https://www.redhat.com/archives/crash-utility/2012-June/msg00029.html

A patch is now getting to work only for ppc targets,
and notes are relocatecd in first ppc's "bt", not in initialization-time.

And I've tested both "bt" diskdump by makedumpfile and netdump by 
/proc/vmcore with patched kernel like
void crash_save_cpu(struct pt_regs *regs, int cpu)
        if ((cpu % 2))
                return;

I was worried about beeing able to catch all of non-contiguous NT_PRSTATUS
notes, alternate with invalid odd notes in every process well,
so I modified test case this time (that's no problem, everything OK).

[After initialization: notes are not relocated yet]
crash> help -D | grep notes
  num_prstatus_notes: 4
           notes_buf: 107a3518
            notes[0]: 107a3518
            notes[1]: 107a3638
            notes[2]: 107a3758
            notes[3]: 107a3878

[Relocate in first bt(only once) and display correctly]
crash> bt
PID: 1000   TASK: eb0cf800  CPU: 4   COMMAND: "bash"
bt: WARNING: cpu#1: not saved crash_notes
bt: WARNING: cpu#3: not saved crash_notes
bt: WARNING: cpu#5: not saved crash_notes
bt: WARNING: cpu#7: not saved crash_notes

R0:  00000001   R1:  ea11be60   R2:  eb0cf800   R3:  00000063
R4:  00000000   R5:  ffffffff   R6:  c043ba2c   R7:  00000000
R8:  00008000   R9:  00000000   R10: 00000000   R11: ea11be70
R12: 28242444   R13: 100b8448   R14: 100b07b8   R15: 100b0894
R16: 00000000   R17: 00000000   R18: 00000000   R19: 1006d270
R20: 00000000   R21: 100f02e0   R22: 00000000   R23: 00000001
R24: c08f1ac8   R25: 00029002   R26: c08f1bac   R27: c08d0000
R28: 00000000   R29: c09ada48   R30: 00000063   R31: ea11be60
NIP: c0423378   MSR: 00021002   OR3: c09ada48   CTR: c0423344
LR:  c0423d8c   XER: 00000000   CCR: 28242444   MQ:  00008000
DAR: 00000000 DSISR: 00800000        Syscall Result: ea11be60
 NIP [00000000c0423378] sysrq_handle_crash
 LR  [00000000c0423d8c] __handle_sysrq

 => PC: c0423378 (sysrq_handle_crash+52) FP: ea11be60
 #0 [ea11be60] sysrq_handle_crash at c0423378
 #1 [ea11be70] __handle_sysrq at c0423d8c
 #2 [ea11bea0] write_sysrq_trigger at c0423ed0
 #3 [ea11beb0] proc_reg_write at c01a79a4
 #4 [ea11bee0] vfs_write at c014ba44
 #5 [ea11bf00] sys_write at c014bcd8
 #6 [ea11bf40] ret_from_syscall at c0013834
 syscall  [c00] exception frame:
R0:  00000004   R1:  bfe54e00   R2:  48027f80   R3:  00000001
R4:  4811d000   R5:  00000002   R6:  00000000   R7:  00000001
R8:  00000000   R9:  00000000   R10: 00000000   R11: 00000200
R12: 28242442   R13: 100b8448   R14: 100b07b8   R15: 100b0894
R16: 00000000   R17: 00000000   R18: 00000000   R19: 1006d270
R20: 00000000   R21: 100f02e0   R22: 1006b4d0   R23: 00000001
R24: 100b0000   R25: 1009b474   R26: bfe54ec8   R27: 00000002
R28: 0fefa400   R29: 4811d000   R30: 0fef9ff4   R31: 00000002
NIP: 0fe61494   MSR: 0002f902   OR3: 00000001   CTR: 0fe06fec
LR:  0fe07050   XER: 00000000   CCR: 28242444   MQ:  00000000
DAR: 4811d000 DSISR: 00800000        Syscall Result: 00000000

[notes has been relocated: Counts num_prstatus_notes even if NULL]
crash> help -D | grep notes
  num_prstatus_notes: 8
           notes_buf: 107a3518
            notes[0]: 107a3518
            notes[1]: 0
            notes[2]: 107a3638
            notes[3]: 0
            notes[4]: 107a3758
            notes[5]: 0
            notes[6]: 107a3878
            notes[7]: 0

Thanks,
Toshi
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 <nakayama.ts@xxxxxxxxxxxxxx>
---
 diskdump.c |   81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 netdump.c  |    3 ++
 ppc.c      |    2 +
 3 files changed, 85 insertions(+), 1 deletions(-)

diff --git a/diskdump.c b/diskdump.c
index e3f04e8..4781659 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1012,12 +1012,91 @@ get_diskdump_panic_task(void)
 extern void get_netdump_regs_x86(struct bt_info *, ulong *, ulong *);
 extern void get_netdump_regs_x86_64(struct bt_info *, ulong *, ulong *);
 
+/*
+ * 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_ppc(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
+relocate_nt_prstatus_percpu_ppc(void **nt_prstatus_percpu,
+				int *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_ppc(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);
+}
+
 static void
 get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
 {
 	Elf32_Nhdr *note;
 	int len;
 
+	if (KDUMP_CMPRS_VALID())
+		relocate_nt_prstatus_percpu_ppc(dd->nt_prstatus_percpu,
+						&dd->num_prstatus_notes);
 	if (KDUMP_CMPRS_VALID() &&
 		(bt->task == tt->panic_task || 
 		(is_task_active(bt->task) && dd->num_prstatus_notes > 1))) {
@@ -1030,7 +1109,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..6cfc1e9 100644
--- a/netdump.c
+++ b/netdump.c
@@ -2589,12 +2589,15 @@ next_sysrq:
 	machdep->get_stack_frame(bt, eip, esp);
 }
 
+extern void relocate_nt_prstatus_percpu_ppc(void **, int *);
 static void
 get_netdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
 {
 	Elf32_Nhdr *note;
 	size_t len;
 
+	relocate_nt_prstatus_percpu_ppc(nd->nt_prstatus_percpu,
+					&nd->num_prstatus_notes);
 	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..7c5f3be 100755
--- a/ppc.c
+++ b/ppc.c
@@ -414,6 +414,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:
-- 
1.7.0.4

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux