diff --git a/include/zephyr/irq.h b/include/zephyr/irq.h index 7cbff4d581c77..b51c2234dc391 100644 --- a/include/zephyr/irq.h +++ b/include/zephyr/irq.h @@ -239,16 +239,13 @@ irq_disconnect_dynamic(unsigned int irq, unsigned int priority, * (for example, ARM) will fail silently if invoked from user mode instead * of generating an exception. * - * @note - * This routine can be called by ISRs or by threads. If it is called by a - * thread, the interrupt lock is thread-specific; this means that interrupts - * remain disabled only while the thread is running. If the thread performs an - * operation that allows another thread to run (for example, giving a semaphore - * or sleeping for N milliseconds), the interrupt lock no longer applies and - * interrupts may be re-enabled while other processing occurs. When the thread - * once again becomes the current thread, the kernel re-establishes its - * interrupt lock; this ensures the thread won't be interrupted until it has - * explicitly released the interrupt lock it established. + * This routine can be called by ISRs and threads. + * + * @warning + * As long as all recursive calls to irq_lock() have not been balanced with + * corresponding irq_unlock() calls, the caller "holds the interrupt lock". + * + * "Holding the interrupt lock" when a context switch occurs is illegal. * * @warning * The lock-out key should never be used to manually re-enable interrupts diff --git a/include/zephyr/spinlock.h b/include/zephyr/spinlock.h index 451e91cbd5475..e6f444ff05fdc 100644 --- a/include/zephyr/spinlock.h +++ b/include/zephyr/spinlock.h @@ -175,6 +175,9 @@ static ALWAYS_INLINE void z_spinlock_validate_post(struct k_spinlock *l) * in uniprocessor contexts such that the locking reduces to an * interrupt mask operation. * + * @warning + * Holding a spinlock when a context switch occurs is illegal. + * * @param l A pointer to the spinlock to lock * @return A key value that must be passed to k_spin_unlock() when the * lock is released. diff --git a/kernel/include/kswap.h b/kernel/include/kswap.h index 0d790ed3a17d6..cff3efab6e90e 100644 --- a/kernel/include/kswap.h +++ b/kernel/include/kswap.h @@ -203,6 +203,16 @@ static inline int z_swap_irqlock(unsigned int key) { int ret; z_check_stack_sentinel(); + +#ifdef CONFIG_SPIN_VALIDATE + /* Refer to comment in do_swap() above for details */ +# ifndef CONFIG_ARM64 + __ASSERT(arch_irq_unlocked(key) || + _current->base.thread_state & (_THREAD_DUMMY | _THREAD_DEAD), + "Context switching while holding lock!"); +# endif /* CONFIG_ARM64 */ +#endif /* CONFIG_SPIN_VALIDATE */ + ret = arch_swap(key); return ret; }