s390/dumpstack: restore reliable indicator for call traces
Before merging all different stack tracers the call traces printed had
an indicator if an entry can be considered reliable or not.
Unreliable entries were put in braces, reliable not. Currently all
lines contain these extra braces.
This patch restores the old behaviour by adding an extra "reliable"
parameter to the callback functions. Only show_trace makes currently
use of it.
Before:
[ 0.804751] Call Trace:
[ 0.804753] ([<000000000017d0e0>] try_to_wake_up+0x318/0x5e0)
[ 0.804756] ([<0000000000161d64>] create_worker+0x174/0x1c0)
After:
[ 0.804751] Call Trace:
[ 0.804753] ([<000000000017d0e0>] try_to_wake_up+0x318/0x5e0)
[ 0.804756] [<0000000000161d64>] create_worker+0x174/0x1c0
Fixes: 758d39ebd3
("s390/dumpstack: merge all four stack tracers")
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
b5003b5f0a
commit
d0208639db
|
@ -192,7 +192,7 @@ struct task_struct;
|
||||||
struct mm_struct;
|
struct mm_struct;
|
||||||
struct seq_file;
|
struct seq_file;
|
||||||
|
|
||||||
typedef int (*dump_trace_func_t)(void *data, unsigned long address);
|
typedef int (*dump_trace_func_t)(void *data, unsigned long address, int reliable);
|
||||||
void dump_trace(dump_trace_func_t func, void *data,
|
void dump_trace(dump_trace_func_t func, void *data,
|
||||||
struct task_struct *task, unsigned long sp);
|
struct task_struct *task, unsigned long sp);
|
||||||
|
|
||||||
|
|
|
@ -38,10 +38,10 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
|
||||||
if (sp < low || sp > high - sizeof(*sf))
|
if (sp < low || sp > high - sizeof(*sf))
|
||||||
return sp;
|
return sp;
|
||||||
sf = (struct stack_frame *) sp;
|
sf = (struct stack_frame *) sp;
|
||||||
|
if (func(data, sf->gprs[8], 0))
|
||||||
|
return sp;
|
||||||
/* Follow the backchain. */
|
/* Follow the backchain. */
|
||||||
while (1) {
|
while (1) {
|
||||||
if (func(data, sf->gprs[8]))
|
|
||||||
return sp;
|
|
||||||
low = sp;
|
low = sp;
|
||||||
sp = sf->back_chain;
|
sp = sf->back_chain;
|
||||||
if (!sp)
|
if (!sp)
|
||||||
|
@ -49,6 +49,8 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
|
||||||
if (sp <= low || sp > high - sizeof(*sf))
|
if (sp <= low || sp > high - sizeof(*sf))
|
||||||
return sp;
|
return sp;
|
||||||
sf = (struct stack_frame *) sp;
|
sf = (struct stack_frame *) sp;
|
||||||
|
if (func(data, sf->gprs[8], 1))
|
||||||
|
return sp;
|
||||||
}
|
}
|
||||||
/* Zero backchain detected, check for interrupt frame. */
|
/* Zero backchain detected, check for interrupt frame. */
|
||||||
sp = (unsigned long) (sf + 1);
|
sp = (unsigned long) (sf + 1);
|
||||||
|
@ -56,7 +58,7 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
|
||||||
return sp;
|
return sp;
|
||||||
regs = (struct pt_regs *) sp;
|
regs = (struct pt_regs *) sp;
|
||||||
if (!user_mode(regs)) {
|
if (!user_mode(regs)) {
|
||||||
if (func(data, regs->psw.addr))
|
if (func(data, regs->psw.addr, 1))
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
low = sp;
|
low = sp;
|
||||||
|
@ -90,7 +92,7 @@ struct return_address_data {
|
||||||
int depth;
|
int depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __return_address(void *data, unsigned long address)
|
static int __return_address(void *data, unsigned long address, int reliable)
|
||||||
{
|
{
|
||||||
struct return_address_data *rd = data;
|
struct return_address_data *rd = data;
|
||||||
|
|
||||||
|
@ -109,9 +111,12 @@ unsigned long return_address(int depth)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(return_address);
|
EXPORT_SYMBOL_GPL(return_address);
|
||||||
|
|
||||||
static int show_address(void *data, unsigned long address)
|
static int show_address(void *data, unsigned long address, int reliable)
|
||||||
{
|
{
|
||||||
printk("([<%016lx>] %pSR)\n", address, (void *)address);
|
if (reliable)
|
||||||
|
printk(" [<%016lx>] %pSR \n", address, (void *)address);
|
||||||
|
else
|
||||||
|
printk("([<%016lx>] %pSR)\n", address, (void *)address);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ static int __init service_level_perf_register(void)
|
||||||
}
|
}
|
||||||
arch_initcall(service_level_perf_register);
|
arch_initcall(service_level_perf_register);
|
||||||
|
|
||||||
static int __perf_callchain_kernel(void *data, unsigned long address)
|
static int __perf_callchain_kernel(void *data, unsigned long address, int reliable)
|
||||||
{
|
{
|
||||||
struct perf_callchain_entry_ctx *entry = data;
|
struct perf_callchain_entry_ctx *entry = data;
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,12 @@ static int __save_address(void *data, unsigned long address, int nosched)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int save_address(void *data, unsigned long address)
|
static int save_address(void *data, unsigned long address, int reliable)
|
||||||
{
|
{
|
||||||
return __save_address(data, address, 0);
|
return __save_address(data, address, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int save_address_nosched(void *data, unsigned long address)
|
static int save_address_nosched(void *data, unsigned long address, int reliable)
|
||||||
{
|
{
|
||||||
return __save_address(data, address, 1);
|
return __save_address(data, address, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
|
||||||
static int __s390_backtrace(void *data, unsigned long address)
|
static int __s390_backtrace(void *data, unsigned long address, int reliable)
|
||||||
{
|
{
|
||||||
unsigned int *depth = data;
|
unsigned int *depth = data;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue