提交 a3266d17 编写于 作者: W Wu Liliu 提交者: guzitao

sw64: reimplement save_stack_trace()

Sunway inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5GFQQ

--------------------------------

It used to save stack-backtrace addresses by SP, which is inaccurate.
In order to implement this function accurately, we provide two ways
to support it.
Signed-off-by: NWu Liliu <wuliliu@wxiat.com>
Signed-off-by: NGu Zitao <guzitao@wxiat.com>
上级 8cc109c4
......@@ -139,40 +139,58 @@ void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
walk_stackframe(task, NULL, print_address_trace, (void *)loglvl);
}
#ifdef CONFIG_STACKTRACE
/*
* Save stack-backtrace addresses into a stack_trace buffer.
*/
void save_stack_trace(struct stack_trace *trace)
struct stack_trace_data {
struct stack_trace *trace;
unsigned int nosched;
};
int save_trace(unsigned long pc, void *d)
{
save_stack_trace_tsk(current, trace);
}
EXPORT_SYMBOL_GPL(save_stack_trace);
struct stack_trace_data *data = d;
struct stack_trace *trace = data->trace;
if (data->nosched && in_sched_functions(pc))
return 0;
if (trace->skip > 0) {
trace->skip--;
return 0;
}
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
trace->entries[trace->nr_entries++] = pc;
return (trace->nr_entries >= trace->max_entries);
}
static void __save_stack_trace(struct task_struct *tsk,
struct stack_trace *trace, unsigned int nosched)
{
unsigned long *sp = (unsigned long *)task_thread_info(tsk)->pcb.ksp;
unsigned long addr;
struct stack_trace_data data;
WARN_ON(trace->nr_entries || !trace->max_entries);
data.trace = trace;
data.nosched = nosched;
walk_stackframe(tsk, NULL, save_trace, &data);
while (!kstack_end(sp)) {
addr = *sp++;
if (__kernel_text_address(addr) &&
!in_sched_functions(addr)) {
if (trace->skip > 0)
trace->skip--;
else
trace->entries[trace->nr_entries++] = addr;
if (trace->nr_entries >= trace->max_entries)
break;
}
}
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
__save_stack_trace(tsk, trace, 1);
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
void save_stack_trace(struct stack_trace *trace)
{
__save_stack_trace(current, trace, 0);
}
EXPORT_SYMBOL_GPL(save_stack_trace);
#endif
static int save_pc(unsigned long pc, void *data)
{
unsigned long *p = data;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册