smp: add a Kconfig option to delay booting secondary CPUs
Usually Zephyr boots all secondary CPUs as a part of system boot. Some applications however need an ability to boot on the main CPU only and enable secondary CPUs selectively at run-time. Add a Kconfig option to support this behaviour. When booting CPUs on demand applications also need helpers to initialise a dummy thread and begin threaded execution on those CPUs, add two such helpers. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
parent
a871f0be49
commit
8d07b7751a
3 changed files with 33 additions and 4 deletions
|
@ -5553,6 +5553,12 @@ extern void z_init_static_threads(void);
|
|||
* @internal
|
||||
*/
|
||||
extern bool z_is_thread_essential(void);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void z_smp_thread_init(void *arg, struct k_thread *thread);
|
||||
void z_smp_thread_swap(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -785,6 +785,14 @@ config SMP
|
|||
When true, kernel will be built with SMP support, allowing
|
||||
more than one CPU to schedule Zephyr tasks at a time.
|
||||
|
||||
config SMP_BOOT_DELAY
|
||||
bool "Delay booting secondary cores"
|
||||
depends on SMP
|
||||
help
|
||||
By default Zephyr will boot all available CPUs during start up.
|
||||
Select this option to skip this and allow architecture code boot
|
||||
secondary CPUs at a later time.
|
||||
|
||||
config MP_NUM_CPUS
|
||||
int "Number of CPUs/cores"
|
||||
default 1
|
||||
|
|
23
kernel/smp.c
23
kernel/smp.c
|
@ -50,28 +50,43 @@ void z_smp_release_global_lock(struct k_thread *thread)
|
|||
}
|
||||
|
||||
#if CONFIG_MP_NUM_CPUS > 1
|
||||
static FUNC_NORETURN void smp_init_top(void *arg)
|
||||
|
||||
void z_smp_thread_init(void *arg, struct k_thread *thread)
|
||||
{
|
||||
atomic_t *cpu_start_flag = arg;
|
||||
struct k_thread dummy_thread;
|
||||
|
||||
/* Wait for the signal to begin scheduling */
|
||||
while (!atomic_get(cpu_start_flag)) {
|
||||
}
|
||||
|
||||
z_dummy_thread_init(&dummy_thread);
|
||||
z_dummy_thread_init(thread);
|
||||
}
|
||||
|
||||
void z_smp_thread_swap(void)
|
||||
{
|
||||
z_swap_unlocked();
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SMP_BOOT_DELAY
|
||||
static FUNC_NORETURN void smp_init_top(void *arg)
|
||||
{
|
||||
struct k_thread dummy_thread;
|
||||
|
||||
z_smp_thread_init(arg, &dummy_thread);
|
||||
smp_timer_init();
|
||||
|
||||
z_swap_unlocked();
|
||||
|
||||
CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void z_smp_init(void)
|
||||
{
|
||||
(void)atomic_clear(&start_flag);
|
||||
|
||||
#if defined(CONFIG_SMP) && (CONFIG_MP_NUM_CPUS > 1)
|
||||
#if CONFIG_MP_NUM_CPUS > 1 && !defined(CONFIG_SMP_BOOT_DELAY)
|
||||
for (int i = 1; i < CONFIG_MP_NUM_CPUS; i++) {
|
||||
arch_start_cpu(i, z_interrupt_stacks[i], CONFIG_ISR_STACK_SIZE,
|
||||
smp_init_top, &start_flag);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue