Kernel: Fix most of mutex + block race conditions

All block functions now take an optional mutex parameter that is
atomically unlocked instead of having the user unlock it before hand.
This prevents a ton of race conditions everywhere in the code!
This commit is contained in:
2025-06-06 03:59:22 +03:00
parent 96d5ed9cc7
commit eecdad50a6
36 changed files with 374 additions and 322 deletions

View File

@@ -46,54 +46,54 @@ namespace Kernel
void DevFileSystem::initialize_device_updater()
{
Process::create_kernel(
[](void*)
[](void* _devfs)
{
auto* devfs = static_cast<DevFileSystem*>(_devfs);
while (true)
{
{
LockGuard _(s_instance->m_device_lock);
for (auto& device : s_instance->m_devices)
LockGuard _(devfs->m_device_lock);
for (auto& device : devfs->m_devices)
device->update();
}
SystemTimer::get().sleep_ms(10);
}
}, nullptr
}, s_instance
);
auto* sync_process = Process::create_kernel();
sync_process->add_thread(MUST(Thread::create_kernel(
[](void*)
[](void* _devfs)
{
auto* devfs = static_cast<DevFileSystem*>(_devfs);
while (true)
{
LockGuard _(s_instance->m_device_lock);
while (!s_instance->m_should_sync)
{
LockFreeGuard _(s_instance->m_device_lock);
s_instance->m_sync_thread_blocker.block_indefinite();
}
LockGuard _(devfs->m_device_lock);
while (!devfs->m_should_sync)
devfs->m_sync_thread_blocker.block_indefinite(&devfs->m_device_lock);
for (auto& device : s_instance->m_devices)
for (auto& device : devfs->m_devices)
if (device->is_storage_device())
if (auto ret = static_cast<StorageDevice*>(device.ptr())->sync_disk_cache(); ret.is_error())
dwarnln("disk sync: {}", ret.error());
s_instance->m_should_sync = false;
s_instance->m_sync_done.unblock();
devfs->m_should_sync = false;
devfs->m_sync_done.unblock();
}
}, nullptr, sync_process
}, s_instance, sync_process
)));
sync_process->add_thread(MUST(Kernel::Thread::create_kernel(
[](void*)
[](void* _devfs)
{
auto* devfs = static_cast<DevFileSystem*>(_devfs);
while (true)
{
SystemTimer::get().sleep_ms(10'000);
s_instance->initiate_sync(false);
devfs->initiate_sync(false);
}
}, nullptr, sync_process
}, s_instance, sync_process
)));
sync_process->register_to_scheduler();
@@ -101,13 +101,11 @@ namespace Kernel
void DevFileSystem::initiate_sync(bool should_block)
{
{
LockGuard _(m_device_lock);
m_should_sync = true;
m_sync_thread_blocker.unblock();
}
if (should_block)
m_sync_done.block_indefinite();
LockGuard _(m_device_lock);
m_should_sync = true;
m_sync_thread_blocker.unblock();
while (should_block && m_should_sync)
m_sync_done.block_indefinite(&m_device_lock);
}
void DevFileSystem::add_device(BAN::RefPtr<Device> device)

View File

@@ -278,14 +278,14 @@ namespace Kernel
BAN::ErrorOr<void> Inode::add_epoll(class Epoll* epoll)
{
LockGuard _(m_epoll_mutex);
SpinLockGuard _(m_epoll_lock);
TRY(m_epolls.push_back(epoll));
return {};
}
void Inode::del_epoll(class Epoll* epoll)
{
LockGuard _(m_epoll_mutex);
SpinLockGuard _(m_epoll_lock);
for (auto it = m_epolls.begin(); it != m_epolls.end(); it++)
{
if (*it != epoll)
@@ -297,7 +297,7 @@ namespace Kernel
void Inode::epoll_notify(uint32_t event)
{
LockGuard _(m_epoll_mutex);
SpinLockGuard _(m_epoll_lock);
for (auto* epoll : m_epolls)
epoll->notify(this, event);
}

View File

@@ -44,6 +44,8 @@ namespace Kernel
void Pipe::on_close(int status_flags)
{
LockGuard _(m_mutex);
if (status_flags & O_WRONLY)
{
auto old_writing_count = m_writing_count.fetch_sub(1);
@@ -71,8 +73,7 @@ namespace Kernel
{
if (m_writing_count == 0)
return 0;
LockFreeGuard lock_free(m_mutex);
TRY(Thread::current().block_or_eintr_or_timeout_ms(m_thread_blocker, 100, false));
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
}
const size_t to_copy = BAN::Math::min<size_t>(buffer.size(), m_buffer_size);
@@ -108,8 +109,7 @@ namespace Kernel
Thread::current().add_signal(SIGPIPE);
return BAN::Error::from_errno(EPIPE);
}
LockFreeGuard lock_free(m_mutex);
TRY(Thread::current().block_or_eintr_or_timeout_ms(m_thread_blocker, 100, false));
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
}
const size_t to_copy = BAN::Math::min(buffer.size(), m_buffer.size() - m_buffer_size);

View File

@@ -1,6 +1,5 @@
#include <kernel/FS/ProcFS/FileSystem.h>
#include <kernel/FS/ProcFS/Inode.h>
#include <kernel/Lock/LockGuard.h>
namespace Kernel
{