[Crash-utility] ppc64 specific changes to support kdump vmcore

Dave Anderson anderson at redhat.com
Tue Feb 14 19:13:40 UTC 2006


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 at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility




More information about the Crash-utility mailing list