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 <[email protected]>
---

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
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to