Skip to content

Commit

Permalink
kernel: smp: put comment on SMP code
Browse files Browse the repository at this point in the history
Adds some comments to the SMP code to, hopefully, make it
a bit more clear to future readers.

Signed-off-by: Daniel Leung <[email protected]>
  • Loading branch information
dcpleung committed Nov 2, 2023
1 parent ce7ae31 commit e2c562f
Showing 1 changed file with 43 additions and 2 deletions.
45 changes: 43 additions & 2 deletions kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,21 @@ static inline FUNC_NORETURN void smp_init_top(void *arg)
struct k_thread dummy_thread;
struct cpu_start *csd = arg;

/* Let the CPU start caller know that this CPU
* has powered up and ready to be initialized.
*/
(void)atomic_set(&cpu_start_data.ready_flag, 1);

/* Wait for the CPU start caller to signal that
* we can start initialization.
*/
wait_for_start_signal(&csd->start_flag);

/* Initialization the dummy thread struct so that
* the scheduler can schedule actual threads to run.
*/
z_dummy_thread_init(&dummy_thread);

#ifdef CONFIG_SYS_CLOCK_EXISTS
smp_timer_init();
#endif
Expand All @@ -130,6 +141,7 @@ static inline FUNC_NORETURN void smp_init_top(void *arg)
}
#endif

/* Let scheduler decide what thread to run next. */
z_swap_unlocked();

CODE_UNREACHABLE; /* LCOV_EXCL_LINE */
Expand All @@ -145,10 +157,21 @@ static void start_cpu(int id, smp_custom_init_fn fn, void *arg)
ARG_UNUSED(arg);
#endif

/* Initialize various CPU structs related to this CPU. */
z_init_cpu(id);

/* Clear the ready flag so the newly powered up CPU can
* signal that it has powered up.
*/
(void)atomic_clear(&cpu_start_data.ready_flag);

/* Power up the CPU */
arch_start_cpu(id, z_interrupt_stacks[id], CONFIG_ISR_STACK_SIZE,
smp_init_top, &cpu_start_data);

/* Wait till the newly powered up CPU to signal that
* it has powered up.
*/
while (!atomic_get(&cpu_start_data.ready_flag)) {
local_delay();
}
Expand All @@ -157,26 +180,44 @@ static void start_cpu(int id, smp_custom_init_fn fn, void *arg)
#ifdef CONFIG_SMP_NEED_CUSTOM_START_FUNC
void k_smp_cpu_custom_start(int id, smp_custom_init_fn fn, void *arg)
{
(void)atomic_set(&cpu_start_data.start_flag, 1); /* async, don't care */
/* We are only starting one CPU so we do not need to synchronize
* across all CPUs using the start_flag. So just set it to 1.
*/
(void)atomic_set(&cpu_start_data.start_flag, 1);

/* Start the CPU! */
start_cpu(id, fn, arg);
}
#endif

void k_smp_cpu_start(int id)
{
(void)atomic_set(&cpu_start_data.start_flag, 1); /* async, don't care */
/* We are only starting one CPU so we do not need to synchronize
* across all CPUs using the start_flag. So just set it to 1.
*/
(void)atomic_set(&cpu_start_data.start_flag, 1);

/* Start the CPU! */
start_cpu(id, NULL, NULL);
}

void z_smp_init(void)
{
/* We are powering up all CPUs and we want to synchronize their
* entry into scheduler. So set the start flag to 0 here.
*/
(void)atomic_clear(&cpu_start_data.start_flag);

/* Just start CPUs one by one. */
unsigned int num_cpus = arch_num_cpus();

for (int i = 1; i < num_cpus; i++) {
start_cpu(i, NULL, NULL);
}

/* Let loose those CPUs so they can start scheduling
* threads to run.
*/
(void)atomic_set(&cpu_start_data.start_flag, 1);
}

Expand Down

0 comments on commit e2c562f

Please sign in to comment.