[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