kernel: timer: Fix race condition in k_timer_start

The documentation suggests that k_timer_start can be invoked from ISR
and preemptive contexts, however, an assertion failure occurs if one
k_timer_start call preempts another for the same timer instance. This
commit mitigates the issue by implementing a spinlock throughout the
k_timer_start function, ensuring thread-safety.

Fixes: #62908

Signed-off-by: Pedro Sousa <sousapedro596@gmail.com>
This commit is contained in:
Pedro Sousa 2023-10-03 22:35:05 +01:00 committed by Carles Cufí
parent afc034e294
commit 4207f4add8

View file

@ -141,7 +141,15 @@ void z_impl_k_timer_start(struct k_timer *timer, k_timeout_t duration,
{
SYS_PORT_TRACING_OBJ_FUNC(k_timer, start, timer, duration, period);
/* Acquire spinlock to ensure safety during concurrent calls to
* k_timer_start for scheduling or rescheduling. This is necessary
* since k_timer_start can be preempted, especially for the same
* timer instance.
*/
k_spinlock_key_t key = k_spin_lock(&lock);
if (K_TIMEOUT_EQ(duration, K_FOREVER)) {
k_spin_unlock(&lock, key);
return;
}
@ -168,6 +176,8 @@ void z_impl_k_timer_start(struct k_timer *timer, k_timeout_t duration,
z_add_timeout(&timer->timeout, z_timer_expiration_handler,
duration);
k_spin_unlock(&lock, key);
}
#ifdef CONFIG_USERSPACE