Skip to content

Commit c7bb423

Browse files
jharris-intelnashif
authored andcommitted
kernel: fix race conditions with z_ready_thread
Several internal APIs wrote thread attributes (return value, mainly) _after_ calling `z_ready_thread`. This is unsafe, at least in SMP, because another core could have already picked up and run the thread. Fixes zephyrproject-rtos#32800. Signed-off-by: James Harris <james.harris@intel.com>
1 parent bb01451 commit c7bb423

File tree

5 files changed

+8
-8
lines changed

5 files changed

+8
-8
lines changed

kernel/condvar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ int z_impl_k_condvar_broadcast(struct k_condvar *condvar)
6464
/* wake up any threads that are waiting to write */
6565
while ((pending_thread = z_unpend_first_thread(&condvar->wait_q)) !=
6666
NULL) {
67+
woken++;
6768
arch_thread_return_value_set(pending_thread, 0);
6869
z_ready_thread(pending_thread);
69-
woken++;
7070
}
7171

7272
z_reschedule(&lock, key);

kernel/futex.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ int z_impl_k_futex_wake(struct k_futex *futex, bool wake_all)
4141
do {
4242
thread = z_unpend_first_thread(&futex_data->wait_q);
4343
if (thread) {
44-
z_ready_thread(thread);
45-
arch_thread_return_value_set(thread, 0);
4644
woken++;
45+
arch_thread_return_value_set(thread, 0);
46+
z_ready_thread(thread);
4747
}
4848
} while (thread && wake_all);
4949

kernel/stack.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ int z_impl_k_stack_push(struct k_stack *stack, stack_data_t data)
108108
first_pending_thread = z_unpend_first_thread(&stack->wait_q);
109109

110110
if (first_pending_thread != NULL) {
111-
z_ready_thread(first_pending_thread);
112-
113111
z_thread_return_value_set_with_data(first_pending_thread,
114112
0, (void *)data);
113+
114+
z_ready_thread(first_pending_thread);
115115
z_reschedule(&stack->lock, key);
116116
goto end;
117117
} else {

kernel/timer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ void z_timer_expiration_handler(struct _timeout *t)
8282
*/
8383
z_unpend_thread_no_timeout(thread);
8484

85-
z_ready_thread(thread);
86-
8785
arch_thread_return_value_set(thread, 0);
86+
87+
z_ready_thread(thread);
8888
}
8989

9090

lib/posix/pthread_mutex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ int pthread_mutex_unlock(pthread_mutex_t *m)
142142
if (thread) {
143143
m->owner = (pthread_t)thread;
144144
m->lock_count++;
145-
z_ready_thread(thread);
146145
arch_thread_return_value_set(thread, 0);
146+
z_ready_thread(thread);
147147
z_reschedule_irqlock(key);
148148
return 0;
149149
}

0 commit comments

Comments
 (0)