[Crash-utility] [PATCH] s390x: Fix linux-3.10 backtrace for interrupt stacks
Dave Anderson
anderson at redhat.com
Tue Jun 4 13:08:52 UTC 2013
----- Original Message -----
> Hi Dave,
>
> The following upstream kernel git commit introduced a crash regression
> in v3.10-rc1 for s390x:
>
> commit dc7ee00d4771b3218b10e09e1071ee6eb176d381
> Date: Wed Apr 24 10:20:43 2013 +0200
>
> s390: lowcore stack pointer offsets
>
> Store the stack pointers in the lowcore for the kernel stack, the async
> stack and the panic stack with the offset required for the first user.
> This avoids an unnecessary add instruction on the system call path.
>
> - lc->async_stack = pcpu->async_stack + ASYNC_SIZE;
> - lc->panic_stack = pcpu->panic_stack + PAGE_SIZE;
> + lc->async_stack = pcpu->async_stack + ASYNC_SIZE
> + - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
> + lc->panic_stack = pcpu->panic_stack + PAGE_SIZE
> + - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
>
> The s390x crash code uses lowcore->panic/async_stack to find out the
> location of the per-cpu stacks. With the above kernel change this is
> no longer correct. For newer kernels with the "pcpu_devices" array
> there is a second location where the stacks are stored. With this
> patch we use the new location if available.
>
> Signed-off-by: Michael Holzheu <holzheu at linux.vnet.ibm.com>
Thanks Michael -- queued for crash-7.0.1.
Dave
> ---
> s390x.c | 42 ++++++++++++++++++++++++++++++++++--------
> 1 file changed, 34 insertions(+), 8 deletions(-)
>
> --- a/s390x.c
> +++ b/s390x.c
> @@ -913,10 +913,34 @@ s390x_get_lowcore(struct bt_info *bt, ch
> }
>
> /*
> + * Get stack address for interrupt stack using the pcpu array
> + */
> +static unsigned long get_int_stack_pcpu(char *stack_name, int cpu)
> +{
> + unsigned long addr;
> +
> + if (!MEMBER_EXISTS("pcpu", stack_name))
> + return 0;
> + addr = symbol_value("pcpu_devices") +
> + cpu * STRUCT_SIZE("pcpu") + MEMBER_OFFSET("pcpu", stack_name);
> + return readmem_ul(addr) + INT_STACK_SIZE;
> +}
> +
> +/*
> + * Get stack address for interrupt stack using the lowcore
> + */
> +static unsigned long get_int_stack_lc(char *stack_name, char *lc)
> +{
> + if (!MEMBER_EXISTS(lc_struct, stack_name))
> + return 0;
> + return ULONG(lc + MEMBER_OFFSET(lc_struct, stack_name));
> +}
> +
> +/*
> * Read interrupt stack (either "async_stack" or "panic_stack");
> */
> -static void get_int_stack(char *stack_name, char *lc, unsigned long *start,
> - unsigned long *end)
> +static void get_int_stack(char *stack_name, int cpu, char *lc,
> + unsigned long *start, unsigned long *end)
> {
> unsigned long stack_addr;
>
> @@ -925,9 +949,10 @@ static void get_int_stack(char *stack_na
> stack_addr = symbol_value("restart_stack");
> stack_addr = readmem_ul(stack_addr);
> } else {
> - if (!MEMBER_EXISTS(lc_struct, stack_name))
> - return;
> - stack_addr = ULONG(lc + MEMBER_OFFSET(lc_struct, stack_name));
> + if (symbol_exists("pcpu_devices"))
> + stack_addr = get_int_stack_pcpu(stack_name, cpu);
> + else
> + stack_addr = get_int_stack_lc(stack_name, lc);
> }
> if (stack_addr == 0)
> return;
> @@ -1157,12 +1182,13 @@ static void s390x_back_trace_cmd(struct
> s390x_print_lowcore(lowcore,bt,1);
> fprintf(fp,"\n");
> if (symbol_exists("restart_stack")) {
> - get_int_stack("restart_stack", lowcore, &low, &high);
> + get_int_stack("restart_stack",
> + cpu, lowcore, &low, &high);
> sp = show_trace(bt, cnt, sp, low, high);
> }
> - get_int_stack("panic_stack", lowcore, &low, &high);
> + get_int_stack("panic_stack", cpu, lowcore, &low, &high);
> sp = show_trace(bt, cnt, sp, low, high);
> - get_int_stack("async_stack", lowcore, &low, &high);
> + get_int_stack("async_stack", cpu, lowcore, &low, &high);
> sp = show_trace(bt, cnt, sp, low, high);
> }
> /*
>
More information about the Crash-utility
mailing list