Without this patch, backtraces of active tasks maybe be of the form "#0 [c0000000700b3a90] (null) at c0000000700b3b50 (unreliable)" for kernel dumps captured with fadump. This patch uses the ptregs saved for active tasks before falling back to stack-search method. Signed-off-by: Hari Bathini <hbathini@xxxxxxxxxxxxxxxxxx> --- Changes from v1: * Ensured that bt output doesn't change for active tasks for kdump and panic task for kdump & fadump while fixing the output for active tasks in case of fadump. diskdump.c | 22 ++++++++++ ppc64.c | 134 +++++++++++++++++++++--------------------------------------- 2 files changed, 68 insertions(+), 88 deletions(-) diff --git a/diskdump.c b/diskdump.c index 48667ad..c080084 100644 --- a/diskdump.c +++ b/diskdump.c @@ -1368,6 +1368,28 @@ get_diskdump_regs_ppc64(struct bt_info *bt, ulong *eip, ulong *esp) { if ((bt->task == tt->panic_task) && DISKDUMP_VALID()) bt->machdep = &dd->sub_header->elf_regs; + else if (KDUMP_CMPRS_VALID() && + (bt->task == tt->panic_task || + (is_task_active(bt->task) && dd->num_prstatus_notes > 1))) { + int cpu; + Elf64_Nhdr *note; + size_t len; + + cpu = bt->tc->processor; + if (dd->nt_prstatus_percpu[cpu] == NULL) { + if(CRASHDEBUG(1)) + error(INFO, + "registers not collected for cpu %d\n", + cpu); + } else { + note = (Elf64_Nhdr *) + dd->nt_prstatus_percpu[cpu]; + len = sizeof(Elf64_Nhdr); + len = roundup(len + note->n_namesz, 4); + bt->machdep = (void *)((char *)note + len + + MEMBER_OFFSET("elf_prstatus", "pr_reg")); + } + } machdep->get_stack_frame(bt, eip, esp); } diff --git a/ppc64.c b/ppc64.c index 8e93979..970b2a1 100644 --- a/ppc64.c +++ b/ppc64.c @@ -65,19 +65,6 @@ static ulong pgd_page_vaddr_l4(ulong pgd); static ulong pud_page_vaddr_l4(ulong pud); static ulong pmd_page_vaddr_l4(ulong pmd); -static inline uint get_ptetype(ulong pte) -{ - uint pte_type = 0; /* 0: regular entry; 1: huge pte; 2: huge pd */ - - if (is_hugepage(pte)) - pte_type = 1; - else if (!(machdep->flags & RADIX_MMU) && - (PAGESIZE() != PPC64_64K_PAGE_SIZE) && is_hugepd(pte)) - pte_type = 2; - - return pte_type; -} - static inline int is_hugepage(ulong pte) { if ((machdep->flags & BOOK3E) || @@ -128,6 +115,19 @@ static inline int is_hugepd(ulong pte) } } +static inline uint get_ptetype(ulong pte) +{ + uint pte_type = 0; /* 0: regular entry; 1: huge pte; 2: huge pd */ + + if (is_hugepage(pte)) + pte_type = 1; + else if (!(machdep->flags & RADIX_MMU) && + (PAGESIZE() != PPC64_64K_PAGE_SIZE) && is_hugepd(pte)) + pte_type = 2; + + return pte_type; +} + static inline ulong hugepage_dir(ulong pte) { if ((machdep->flags & BOOK3E) || @@ -2219,60 +2219,6 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs, } /* - * 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 || !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]; - if (IS_KVADDR(*ksp)) { - readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value", - FAULT_ON_ERROR); - *nip = unip; - } else { - if (IN_TASK_VMA(bt_in->task, *ksp)) - fprintf(fp, "%0lx: Task is running in user space\n", - bt_in->task); - else - fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n", - bt_in->task, *ksp); - *nip = pt_regs->nip; - } - - 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); - if (!IS_KVADDR(*ksp)) - return FALSE; - - 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)); - - return TRUE; -} - -/* * Get the starting point for the active cpus in a diskdump/netdump. */ static int @@ -2291,25 +2237,14 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) struct ppc64_pt_regs *pt_regs; struct syment *sp; - /* - * 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; - - panic_task = tt->panic_task == bt->task ? TRUE : FALSE; + panic_task = tt->panic_task == bt->task ? TRUE : FALSE; check_hardirq = check_softirq = tt->flags & IRQSTACKS ? TRUE : FALSE; - if (panic_task && bt->machdep) { - pt_regs = (struct ppc64_pt_regs *)bt->machdep; - ur_nip = pt_regs->nip; - ur_ksp = pt_regs->gpr[1]; - } else if (bt->task != tt->panic_task) { + + if (bt->task != tt->panic_task) { char cpu_frozen = FALSE; /* * Determine whether the CPU responded to an IPI. @@ -2428,15 +2363,38 @@ retry: alter_stackbuf(bt); check_intrstack = FALSE; goto retry; - } + } + /* - * We didn't find what we were looking for, so just use what was - * passed in the ELF header. + * We didn't find what we were looking for, so try to use + * the SP and IP values saved in ptregs. */ - if (ur_nip && ur_ksp) { - *nip = ur_nip; - *ksp = ur_ksp; - return TRUE; + pt_regs = (struct ppc64_pt_regs *)bt_in->machdep; + if (!pt_regs || !pt_regs->gpr[1]) { + /* + * Not collected regs. May be the corresponding CPU did not + * respond to an IPI. + */ + if (CRASHDEBUG(1)) + fprintf(fp, "%0lx: GPR1(SP) register value not saved\n", + bt_in->task); + } else { + *ksp = pt_regs->gpr[1]; + if (IS_KVADDR(*ksp)) { + readmem(*ksp+16, KVADDR, nip, sizeof(ulong), + "Regs NIP value", FAULT_ON_ERROR); + return TRUE; + } else { + if (IN_TASK_VMA(bt_in->task, *ksp)) + fprintf(fp, "%0lx: Task is running in user space\n", + bt_in->task); + else + fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n", + bt_in->task, *ksp); + *nip = pt_regs->nip; + ppc64_print_regs(pt_regs); + return FALSE; + } } console("ppc64_get_dumpfile_stack_frame: cannot find SP for panic task\n"); -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility