From 71559291e10da649567b0f753ae58a04bbab7c43 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Fri, 16 Aug 2024 18:48:44 +0800 Subject: [PATCH] sched: replace sync pause with async pause for sched_backtrace Signed-off-by: hujun5 --- sched/sched/sched_backtrace.c | 88 +++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 9 deletions(-) diff --git a/sched/sched/sched_backtrace.c b/sched/sched/sched_backtrace.c index 6e95b45b51a21..dec02e4854edf 100644 --- a/sched/sched/sched_backtrace.c +++ b/sched/sched/sched_backtrace.c @@ -30,6 +30,59 @@ #include "sched.h" +#ifdef CONFIG_ARCH_HAVE_BACKTRACE + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +#ifdef CONFIG_SMP +struct backtrace_arg_s +{ + pid_t pid; + FAR void **buffer; + int size; + int skip; + cpu_set_t saved_affinity; + uint16_t saved_flags; + bool need_restore; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int sched_backtrace_handler(FAR void *cookie) +{ + FAR struct backtrace_arg_s *arg = cookie; + FAR struct tcb_s *tcb; + irqstate_t flags; + + flags = enter_critical_section(); + + tcb = nxsched_get_tcb(arg->pid); + + if (!tcb || tcb->task_state == TSTATE_TASK_INVALID || + (tcb->flags & TCB_FLAG_EXIT_PROCESSING) != 0) + { + /* There is no TCB with this pid or, if there is, it is not a task. */ + + leave_critical_section(flags); + return -ESRCH; + } + + if (arg->need_restore) + { + tcb->affinity = arg->saved_affinity; + tcb->flags = arg->saved_flags; + } + + leave_critical_section(flags); + + return up_backtrace(tcb, arg->buffer, arg->size, arg->skip); +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -44,7 +97,6 @@ * ****************************************************************************/ -#ifdef CONFIG_ARCH_HAVE_BACKTRACE int sched_backtrace(pid_t tid, FAR void **buffer, int size, int skip) { FAR struct tcb_s *tcb = this_task(); @@ -65,18 +117,36 @@ int sched_backtrace(pid_t tid, FAR void **buffer, int size, int skip) if (tcb->task_state == TSTATE_TASK_RUNNING && g_nx_initstate != OSINIT_PANIC) { - up_cpu_pause(tcb->cpu); + struct backtrace_arg_s arg; + + if ((tcb->flags & TCB_FLAG_CPU_LOCKED) != 0) + { + arg.pid = tcb->pid; + arg.need_restore = false; + } + else + { + arg.pid = tcb->pid; + arg.saved_flags = tcb->flags; + arg.saved_affinity = tcb->affinity; + arg.need_restore = true; + + tcb->flags |= TCB_FLAG_CPU_LOCKED; + CPU_SET(tcb->cpu, &tcb->affinity); + } + + arg.buffer = buffer; + arg.size = size; + arg.skip = skip; + ret = nxsched_smp_call_single(tcb->cpu, + sched_backtrace_handler, + &arg, true); } + else #endif - - ret = up_backtrace(tcb, buffer, size, skip); -#ifdef CONFIG_SMP - if (tcb->task_state == TSTATE_TASK_RUNNING && - g_nx_initstate != OSINIT_PANIC) { - up_cpu_resume(tcb->cpu); + ret = up_backtrace(tcb, buffer, size, skip); } -#endif } leave_critical_section(flags);