From f37e0c6e4d56202872116888cba71aa8ce40347a Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Wed, 20 Feb 2019 10:11:24 -0800 Subject: [PATCH] kernel/spinlock: Fix race in spinlock validation The k_spin_lock() validation was setting the new owner of the spinlock BEFORE the actual lock was taken, so it could race against other processors trying the same thing. Split the modification step out into a separate function that can be called after we affirmatively have the lock. Signed-off-by: Andy Ross --- include/spinlock.h | 4 ++++ kernel/thread.c | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/spinlock.h b/include/spinlock.h index d732310e710..5161443eca3 100644 --- a/include/spinlock.h +++ b/include/spinlock.h @@ -38,6 +38,7 @@ static inline void z_arch_irq_unlock(int key) struct k_spinlock; int z_spin_lock_valid(struct k_spinlock *l); int z_spin_unlock_valid(struct k_spinlock *l); +void z_spin_lock_set_owner(struct k_spinlock *l); #define SPIN_VALIDATE #endif #endif @@ -81,6 +82,9 @@ static ALWAYS_INLINE k_spinlock_key_t k_spin_lock(struct k_spinlock *l) } #endif +#ifdef SPIN_VALIDATE + z_spin_lock_set_owner(l); +#endif return k; } diff --git a/kernel/thread.c b/kernel/thread.c index 6c70458b89e..5f8cab4883f 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -723,7 +723,6 @@ int z_spin_lock_valid(struct k_spinlock *l) return 0; } } - l->thread_cpu = _current_cpu->id | (u32_t)_current; return 1; } @@ -735,4 +734,10 @@ int z_spin_unlock_valid(struct k_spinlock *l) l->thread_cpu = 0; return 1; } + +void z_spin_lock_set_owner(struct k_spinlock *l) +{ + l->thread_cpu = _current_cpu->id | (u32_t)_current; +} + #endif