From fd340ebf3170da6c40071ce86ec5ac8df934ba11 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Fri, 19 Apr 2024 15:03:09 -0700 Subject: [PATCH] sched: Optimize dummy thread usage on SMP Nicolas Pitre points out that since these thread structs are just dummies for the context swtiching, they can be presumed to be "write only" and thus there's no point in having one per CPU, everyone can share the same one. The only gotcha is that we never really documented (nor really have a place to document) that rule, so it's not theoretically impossible for an architecture to read back what it might have written underneath arch_switch(). Leave this in a separate commit for bisection purposes, but the risk seems very low. Signed-off-by: Andy Ross --- kernel/include/ksched.h | 2 +- kernel/init.c | 2 +- kernel/sched.c | 4 ++-- kernel/smp.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/include/ksched.h b/kernel/include/ksched.h index dff27177022..058e44ebef3 100644 --- a/kernel/include/ksched.h +++ b/kernel/include/ksched.h @@ -37,7 +37,7 @@ BUILD_ASSERT(K_LOWEST_APPLICATION_THREAD_PRIO #define Z_ASSERT_VALID_PRIO(prio, entry_point) __ASSERT((prio) == -1, "") #endif /* CONFIG_MULTITHREADING */ -extern struct k_thread _thread_dummies[CONFIG_MP_MAX_NUM_CPUS]; +extern struct k_thread _thread_dummy; void z_sched_init(void); void z_move_thread_to_end_of_prio_q(struct k_thread *thread); diff --git a/kernel/init.c b/kernel/init.c index f6edb54f5a9..eaffb6ce763 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -650,7 +650,7 @@ FUNC_NORETURN void z_cstart(void) LOG_CORE_INIT(); #if defined(CONFIG_MULTITHREADING) - z_dummy_thread_init(&_thread_dummies[0]); + z_dummy_thread_init(&_thread_dummy); #endif /* CONFIG_MULTITHREADING */ /* do any necessary initialization of static devices */ z_device_state_init(); diff --git a/kernel/sched.c b/kernel/sched.c index 00d0efdb4db..6ee12648560 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -33,7 +33,7 @@ struct k_spinlock _sched_spinlock; /* Storage to "complete" the context switch from an invalid/incomplete thread * context (ex: exiting an ISR that aborted _current) */ -__incoherent struct k_thread _thread_dummies[CONFIG_MP_MAX_NUM_CPUS]; +__incoherent struct k_thread _thread_dummy; static void update_cache(int preempt_ok); static void halt_thread(struct k_thread *thread, uint8_t new_state); @@ -1364,7 +1364,7 @@ static void halt_thread(struct k_thread *thread, uint8_t new_state) * code. */ if (dummify && !IS_ENABLED(CONFIG_ARCH_POSIX)) { - z_dummy_thread_init(&_thread_dummies[_current_cpu->id]); + z_dummy_thread_init(&_thread_dummy); } } } diff --git a/kernel/smp.c b/kernel/smp.c index f04a7270f31..704bfcd9caa 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -122,7 +122,7 @@ static inline void smp_init_top(void *arg) /* Initialize the dummy thread struct so that * the scheduler can schedule actual threads to run. */ - z_dummy_thread_init(&_thread_dummies[arch_curr_cpu()->id]); + z_dummy_thread_init(&_thread_dummy); } #ifdef CONFIG_SYS_CLOCK_EXISTS