From 0ca7150f90fc0a44ea1d14936afb027eed3654cd Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Tue, 13 Sep 2022 10:13:40 -0700 Subject: [PATCH] kernel/idle: Fix !SCHED_IPI_SUPPORTED The requirement for k_yield() to handle "yielding" in the idle thread was removed a while back, but it missed a spot where we'd try to yield in the fallback loop on bringup platforms that lack an IPI. This now crashes, because yield now unconditionally tries to reschedule the current thread, which doesn't work for idle threads that don't live in the run queue. Just make it a busy loop calling swap(), even simpler. Fixes #50119 Signed-off-by: Andy Ross --- kernel/idle.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/kernel/idle.c b/kernel/idle.c index ae6fffd83f0..b5e9fa7d514 100644 --- a/kernel/idle.c +++ b/kernel/idle.c @@ -39,19 +39,19 @@ void idle(void *unused1, void *unused2, void *unused3) __ASSERT_NO_MSG(_current->base.prio >= 0); while (true) { - /* SMP systems without a working IPI can't - * actual enter an idle state, because they - * can't be notified of scheduler changes - * (i.e. threads they should run). They just - * spin in a yield loop. This is intended as - * a fallback configuration for new platform - * bringup. + /* SMP systems without a working IPI can't actual + * enter an idle state, because they can't be notified + * of scheduler changes (i.e. threads they should + * run). They just spin instead, with a minimal + * relaxation loop to prevent hammering the scheduler + * lock and/or timer driver. This is intended as a + * fallback configuration for new platform bringup. */ if (IS_ENABLED(CONFIG_SMP) && !IS_ENABLED(CONFIG_SCHED_IPI_SUPPORTED)) { - k_busy_wait(100); - k_yield(); - continue; + for (volatile int i = 0; i < 100000; i++) + ; + z_swap_unlocked(); } /* Note weird API: k_cpu_idle() is called with local