[PATCH v9 03/11] arm64: Make get_wchan() use arch_stack_walk()

From: madvenka
Date: Thu Oct 14 2021 - 22:35:08 EST


From: "Madhavan T. Venkataraman" <madvenka@xxxxxxxxxxxxxxxxxxx>

Currently, get_wchan() in ARM64 code walks the stack using start_backtrace()
and unwind_frame(). Make it use arch_stack_walk() instead. This makes
maintenance easier.

Signed-off-by: Madhavan T. Venkataraman <madvenka@xxxxxxxxxxxxxxxxxxx>
---
arch/arm64/kernel/process.c | 38 ++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index c8989b999250..48ed89acce0d 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -544,11 +544,27 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
return last;
}

+struct wchan_info {
+ unsigned long pc;
+ int count;
+};
+
+static bool get_wchan_cb(void *arg, unsigned long pc)
+{
+ struct wchan_info *wchan_info = arg;
+
+ if (!in_sched_functions(pc)) {
+ wchan_info->pc = pc;
+ return false;
+ }
+ return wchan_info->count++ < 16;
+}
+
unsigned long get_wchan(struct task_struct *p)
{
- struct stackframe frame;
- unsigned long stack_page, ret = 0;
- int count = 0;
+ unsigned long stack_page;
+ struct wchan_info wchan_info;
+
if (!p || p == current || task_is_running(p))
return 0;

@@ -556,20 +572,12 @@ unsigned long get_wchan(struct task_struct *p)
if (!stack_page)
return 0;

- start_backtrace(&frame, thread_saved_fp(p), thread_saved_pc(p));
+ wchan_info.pc = 0;
+ wchan_info.count = 0;
+ arch_stack_walk(get_wchan_cb, &wchan_info, p, NULL);

- do {
- if (unwind_frame(p, &frame))
- goto out;
- if (!in_sched_functions(frame.pc)) {
- ret = frame.pc;
- goto out;
- }
- } while (count++ < 16);
-
-out:
put_task_stack(p);
- return ret;
+ return wchan_info.pc;
}

unsigned long arch_align_stack(unsigned long sp)
--
2.25.1