From f205fee3da57c467ce1cf9cf33f88d529e79875b Mon Sep 17 00:00:00 2001 From: Sairaj Kodilkar Date: Tue, 31 Jan 2023 12:22:01 +0530 Subject: [PATCH] lib/uklock: Provide irqf wrappers for uk_spinlock Holding a spinlock which is required by an interrupt handler, causes a deadlock. To avoid this, the programmer must disable the interrupt before acquiring such spinlocks. This involves saving the interrupt flags before acquiring the spinlock and restoring them after releasing the spinlock. This commit provides versions of the ukplat_spin_* macros for the uk_spinlock. Co-authored-by: Marc Rittinghaus Signed-off-by: Sairaj Kodilkar Signed-off-by: Marc Rittinghaus Reviewed-by: Radu Nichita Reviewed-by: Andra Paraschiv Approved-by: Razvan Deaconescu Tested-by: Unikraft CI GitHub-Closes: #476 --- lib/uklock/include/uk/spinlock.h | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/lib/uklock/include/uk/spinlock.h b/lib/uklock/include/uk/spinlock.h index 652d01e2b..df270e83a 100644 --- a/lib/uklock/include/uk/spinlock.h +++ b/lib/uklock/include/uk/spinlock.h @@ -33,6 +33,9 @@ #ifndef __UK_SPINLOCK_H__ #define __UK_SPINLOCK_H__ +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -74,6 +77,44 @@ extern "C" { #endif /* CONFIG_LIBUKLOCK_TICKETLOCK */ +#define uk_spin_lock_irq(lock) \ + do { \ + ukplat_lcpu_disable_irq(); \ + uk_spin_lock(lock); \ + } while (0) + +#define uk_spin_unlock_irq(lock) \ + do { \ + uk_spin_unlock(lock); \ + ukplat_lcpu_enable_irq(); \ + } while (0) + +#define uk_spin_trylock_irq(lock) \ + do { \ + ukplat_lcpu_disable_irq(); \ + if (unlikely(uk_spin_trylock(lock) == 0)) \ + ukplat_lcpu_enable_irq(); \ + } while (0) + +#define uk_spin_lock_irqsave(lock, flags) \ + do { \ + flags = ukplat_lcpu_save_irqf(); \ + uk_spin_lock(lock); \ + } while (0) + +#define uk_spin_unlock_irqrestore(lock, flags) \ + do { \ + uk_spin_unlock(lock); \ + ukplat_lcpu_restore_irqf(flags); \ + } while (0) + +#define uk_spin_trylock_irqsave(lock, flags) \ + do { \ + flags = ukplat_lcpu_save_irqf(); \ + if (unlikely(uk_spin_trylock(lock) == 0)) \ + ukplat_lcpu_restore_irqf(flags); \ + } while (0) + #ifdef __cplusplus } #endif -- 2.39.5