summaryrefslogtreecommitdiff
path: root/Kernel/Locking/Mutex.cpp
diff options
context:
space:
mode:
authorAndrew Kaster <akaster@serenityos.org>2021-08-22 22:06:44 -0600
committerAndreas Kling <kling@serenityos.org>2021-08-28 20:53:38 +0200
commit72de228695f3b689825768a2cf60fe98b9c8c65d (patch)
tree93f599ac5ebd6cf3146d230d582f3b9608d79269 /Kernel/Locking/Mutex.cpp
parent4f2520674caa937dedc6572fdf310f5e0ae42074 (diff)
downloadserenity-72de228695f3b689825768a2cf60fe98b9c8c65d.zip
Kernel: Verify interrupts are disabled when interacting with Mutexes
This should help prevent deadlocks where a thread blocks on a Mutex while interrupts are disabled, and makes it impossible for the holder of the Mutex to make forward progress because it cannot be scheduled in. Hide it behind a new debug macro LOCK_IN_CRITICAL_DEBUG for now, because Ext2FS takes a series of Mutexes from the page fault handler, which executes with interrupts disabled.
Diffstat (limited to 'Kernel/Locking/Mutex.cpp')
-rw-r--r--Kernel/Locking/Mutex.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/Kernel/Locking/Mutex.cpp b/Kernel/Locking/Mutex.cpp
index 829001958b..14ad0f70ed 100644
--- a/Kernel/Locking/Mutex.cpp
+++ b/Kernel/Locking/Mutex.cpp
@@ -18,6 +18,8 @@ void Mutex::lock(Mode mode, [[maybe_unused]] LockLocation const& location)
// NOTE: This may be called from an interrupt handler (not an IRQ handler)
// and also from within critical sections!
VERIFY(!Processor::current_in_irq());
+ if constexpr (LOCK_IN_CRITICAL_DEBUG)
+ VERIFY_INTERRUPTS_ENABLED();
VERIFY(mode != Mode::Unlocked);
auto current_thread = Thread::current();
@@ -143,6 +145,8 @@ void Mutex::unlock()
{
// NOTE: This may be called from an interrupt handler (not an IRQ handler)
// and also from within critical sections!
+ if constexpr (LOCK_IN_CRITICAL_DEBUG)
+ VERIFY_INTERRUPTS_ENABLED();
VERIFY(!Processor::current_in_irq());
auto current_thread = Thread::current();
SpinlockLocker lock(m_lock);
@@ -198,6 +202,8 @@ void Mutex::unlock()
void Mutex::block(Thread& current_thread, Mode mode, SpinlockLocker<Spinlock<u8>>& lock, u32 requested_locks)
{
+ if constexpr (LOCK_IN_CRITICAL_DEBUG)
+ VERIFY_INTERRUPTS_ENABLED();
auto& blocked_thread_list = thread_list_for_mode(mode);
VERIFY(!blocked_thread_list.contains(current_thread));
blocked_thread_list.append(current_thread);