diff --git a/kernel/idle.c b/kernel/idle.c index abf7a8e1829..e9cef6f85eb 100644 --- a/kernel/idle.c +++ b/kernel/idle.c @@ -19,6 +19,10 @@ #define IDLE_THRESH 1 #endif +/* Fallback idle spin loop for SMP platforms without a working IPI */ +#define SMP_FALLBACK \ + (defined(CONFIG_SMP) && !defined(CONFIG_SCHED_IPI_SUPPORTED)) + #ifdef CONFIG_SYS_POWER_MANAGEMENT /* * Used to allow _sys_suspend() implementation to control notification @@ -56,7 +60,7 @@ void __attribute__((weak)) _sys_resume_from_deep_sleep(void) * * @return N/A */ -#ifndef CONFIG_SMP +#if !SMP_FALLBACK static void set_kernel_idle_time_in_ticks(s32_t ticks) { #ifdef CONFIG_SYS_POWER_MANAGEMENT @@ -145,18 +149,12 @@ void idle(void *unused1, void *unused2, void *unused3) __idle_time_stamp = k_cycle_get_32(); #endif -#ifdef CONFIG_SMP - /* Simplified idle for SMP CPUs pending driver support. The - * busy waiting is needed to prevent lock contention. Long - * term we need to wake up idle CPUs with an IPI. - */ while (true) { +#if SMP_FALLBACK k_busy_wait(100); k_yield(); - } #else - for (;;) { - (void)irq_lock(); + (void)z_arch_irq_lock(); sys_power_save_idle(); IDLE_YIELD_IF_COOP(); diff --git a/kernel/sched.c b/kernel/sched.c index f682899b3a6..3456587403a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -336,6 +336,9 @@ void z_add_thread_to_ready_q(struct k_thread *thread) _priq_run_add(&_kernel.ready_q.runq, thread); z_mark_thread_as_queued(thread); update_cache(0); +#ifdef CONFIG_SCHED_IPI_SUPPORTED + z_arch_sched_ipi(); +#endif } }