mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-10 07:50:04 +00:00
93a4fa622e
1. Use common arch_stack_walk() infrastructure to avoid duplicated code and avoid taking care of the stack storage and filtering. 2. Add sched_ra (means sched return address) and sched_cfa (means sched call frame address) to thread_info, and store them in switch_to(). 3. Add __get_wchan() implementation. Now we can print the process stack and wait channel by cat /proc/*/stack and /proc/*/wchan. Signed-off-by: Qing Zhang <zhangqing@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
38 lines
946 B
C
38 lines
946 B
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Stack trace management functions
|
|
*
|
|
* Copyright (C) 2022 Loongson Technology Corporation Limited
|
|
*/
|
|
#include <linux/sched.h>
|
|
#include <linux/stacktrace.h>
|
|
|
|
#include <asm/stacktrace.h>
|
|
#include <asm/unwind.h>
|
|
|
|
void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
|
|
struct task_struct *task, struct pt_regs *regs)
|
|
{
|
|
unsigned long addr;
|
|
struct pt_regs dummyregs;
|
|
struct unwind_state state;
|
|
|
|
regs = &dummyregs;
|
|
|
|
if (task == current) {
|
|
regs->regs[3] = (unsigned long)__builtin_frame_address(0);
|
|
regs->csr_era = (unsigned long)__builtin_return_address(0);
|
|
} else {
|
|
regs->regs[3] = thread_saved_fp(task);
|
|
regs->csr_era = thread_saved_ra(task);
|
|
}
|
|
|
|
regs->regs[1] = 0;
|
|
for (unwind_start(&state, task, regs);
|
|
!unwind_done(&state); unwind_next_frame(&state)) {
|
|
addr = unwind_get_return_address(&state);
|
|
if (!addr || !consume_entry(cookie, addr))
|
|
break;
|
|
}
|
|
}
|