提交 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) ...@@ -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); walk_stackframe(task, NULL, print_address_trace, (void *)loglvl);
} }
#ifdef CONFIG_STACKTRACE
/* /*
* Save stack-backtrace addresses into a stack_trace buffer. * 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); struct stack_trace_data *data = d;
} struct stack_trace *trace = data->trace;
EXPORT_SYMBOL_GPL(save_stack_trace);
if (data->nosched && in_sched_functions(pc))
return 0;
if (trace->skip > 0) {
trace->skip--;
return 0;
}
trace->entries[trace->nr_entries++] = pc;
return (trace->nr_entries >= trace->max_entries);
}
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 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; struct stack_trace_data data;
unsigned long addr;
data.trace = trace;
WARN_ON(trace->nr_entries || !trace->max_entries); data.nosched = nosched;
while (!kstack_end(sp)) { walk_stackframe(tsk, NULL, save_trace, &data);
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) if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX; 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); 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) static int save_pc(unsigned long pc, void *data)
{ {
unsigned long *p = data; unsigned long *p = data;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册