Skip to content

Commit

Permalink
smp: fix a race when starting / resuming multiple CPUs
Browse files Browse the repository at this point in the history
cpu_start_fn is global, it's used by the initiator CPU to start or
resume secondary CPUs. However it's possible, that the initiator CPU
goes ahead and starts a second secondary CPU before the first one has
finished using the object. Fix this by creating a local copy of the
global object.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
  • Loading branch information
lyakh authored and henrikbrixandersen committed Feb 16, 2024
1 parent f3d5918 commit 09cf3e0
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static void wait_for_start_signal(atomic_t *start_flag)
static inline void smp_init_top(void *arg)
{
struct k_thread dummy_thread;
struct cpu_start_cb *csc = arg;
struct cpu_start_cb csc = arg ? *(struct cpu_start_cb *)arg : (struct cpu_start_cb){0};

/* Let start_cpu() know that this CPU has powered up. */
(void)atomic_set(&ready_flag, 1);
Expand All @@ -119,25 +119,25 @@ static inline void smp_init_top(void *arg)
*/
wait_for_start_signal(&cpu_start_flag);

if ((csc == NULL) || csc->invoke_sched) {
if ((arg == NULL) || csc.invoke_sched) {
/* Initialize 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
if ((csc == NULL) || csc->reinit_timer) {
if ((arg == NULL) || csc.reinit_timer) {
smp_timer_init();
}
#endif

/* Do additional initialization steps if needed. */
if ((csc != NULL) && (csc->fn != NULL)) {
csc->fn(csc->arg);
if (csc.fn != NULL) {
csc.fn(csc.arg);
}

if ((csc != NULL) && !csc->invoke_sched) {
if ((arg != NULL) && !csc.invoke_sched) {
/* Don't invoke scheduler. */
return;
}
Expand Down

0 comments on commit 09cf3e0

Please sign in to comment.