diff options
author | Andrew Kaster <akaster@serenityos.org> | 2021-08-22 22:06:44 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-28 20:53:38 +0200 |
commit | 72de228695f3b689825768a2cf60fe98b9c8c65d (patch) | |
tree | 93f599ac5ebd6cf3146d230d582f3b9608d79269 /Kernel/Locking/Mutex.cpp | |
parent | 4f2520674caa937dedc6572fdf310f5e0ae42074 (diff) | |
download | serenity-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.cpp | 6 |
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); |