Kernel: Rework spinlock usage when blocking the current thread

The old SpinLockAsMutex was pretty confusing first of all. It also was
causing the issue thats been around for maybe a year now which is the
only consistently happening kernel panic. I've been pretty confused
about this and finally figured out what was causing this.

The main issue was that we were accidentally enabling interrupts when
blocking a thread that passed SpinLockAsMutex from normally interrupt
enabled context. This led to receiving IPI for thread unblock while
we were actively blocking the thread. I'm very suprized this had't
caused any more serious issues than occasional kernel panics :^)
This commit is contained in:
2026-07-20 04:07:23 +03:00
parent edc95e1c09
commit 5329ec5912
21 changed files with 105 additions and 133 deletions
+9 -9
View File
@@ -3,7 +3,7 @@
#include <kernel/Device/DeviceNumbers.h>
#include <kernel/FS/DevFS/FileSystem.h>
#include <kernel/Input/InputDevice.h>
#include <kernel/Lock/SpinLockAsMutex.h>
#include <kernel/Lock/BlockableSpinLock.h>
#include <kernel/Terminal/TTY.h>
#include <LibInput/Joystick.h>
@@ -245,8 +245,8 @@ namespace Kernel
while (m_event_count == 0)
{
// FIXME: should m_mutex be unlocked?
SpinLockGuardAsMutex smutex(guard);
TRY(Thread::current().block_or_eintr_indefinite(m_event_thread_blocker, &smutex));
BlockableSpinLock block(m_event_lock);
TRY(Thread::current().block_or_eintr_indefinite(m_event_thread_blocker, &block));
}
memcpy(buffer.data(), &m_event_buffer[m_event_tail * m_event_size], m_event_size);
@@ -289,8 +289,8 @@ namespace Kernel
if (s_tty_keyboard_events.empty())
{
SpinLockGuardAsMutex smutex(guard);
s_tty_keyboard_event_blocker.block_indefinite(&smutex);
BlockableSpinLock block(s_tty_keyboard_event_lock);
s_tty_keyboard_event_blocker.block_indefinite(&block);
continue;
}
@@ -350,8 +350,8 @@ namespace Kernel
return bytes;
}
SpinLockGuardAsMutex smutex(keyboard_guard);
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &smutex));
BlockableSpinLock block(s_keyboard_lock);
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &block));
}
}
@@ -407,8 +407,8 @@ namespace Kernel
return bytes;
}
SpinLockGuardAsMutex smutex(mouse_guard);
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &smutex));
BlockableSpinLock block(s_mouse_lock);
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &block));
}
}