diff options
author | Raul E Rangel <rrangel@chromium.org> | 2021-07-14 11:38:20 -0600 |
---|---|---|
committer | Raul Rangel <rrangel@chromium.org> | 2021-07-18 15:14:00 +0000 |
commit | a98d302fe9dcce13a1c60b4bdfaf2e713fd11b51 (patch) | |
tree | 88354526393b35f6e3a598ba61c90b9a7521d01e | |
parent | 9ba36abdc542b881df7e0f0c5883a9dab1b9bc50 (diff) |
x86/smp/spinlock: Disable thread coop when taking spinlock
Switching threads while holding a spinlock can lead to a deadlock. This
happens if you have two thread trying to print to the serial console
because the uart code uses udelay.
BUG=b:179699789
TEST=Boot guybrush and no longer see a deadlock when printing to
console from a second thread.
Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Change-Id: I1b929070b7f175965d4f37be693462fef26be052
Reviewed-on: https://review.coreboot.org/c/coreboot/+/56320
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
-rw-r--r-- | src/arch/x86/include/arch/smp/spinlock.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h index 799ac2c8b8..0c06c22bba 100644 --- a/src/arch/x86/include/arch/smp/spinlock.h +++ b/src/arch/x86/include/arch/smp/spinlock.h @@ -3,6 +3,8 @@ #ifndef ARCH_SMP_SPINLOCK_H #define ARCH_SMP_SPINLOCK_H +#include <thread.h> + /* * Your basic SMP spinlocks, allowing only a single CPU anywhere */ @@ -54,10 +56,16 @@ static __always_inline void spin_lock(spinlock_t *lock) __asm__ __volatile__( spin_lock_string : "=m" (lock->lock) : : "memory"); + + /* Switching contexts while holding a spinlock will lead to deadlocks */ + thread_coop_disable(); + } static __always_inline void spin_unlock(spinlock_t *lock) { + thread_coop_enable(); + __asm__ __volatile__( spin_unlock_string : "=m" (lock->lock) : : "memory"); |