From 4207f4add8ffe3e027844c36fe26b7d727e1542e Mon Sep 17 00:00:00 2001 From: Pedro Sousa Date: Tue, 3 Oct 2023 22:35:05 +0100 Subject: [PATCH] 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 --- kernel/timer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kernel/timer.c b/kernel/timer.c index 24fe71c7f67..9994ae49b64 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -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