diff --git a/kernel/include/kernel/FS/DevFS/FileSystem.h b/kernel/include/kernel/FS/DevFS/FileSystem.h index 18ebbce588..5244a9ad8d 100644 --- a/kernel/include/kernel/FS/DevFS/FileSystem.h +++ b/kernel/include/kernel/FS/DevFS/FileSystem.h @@ -22,6 +22,7 @@ namespace Kernel void add_inode(BAN::StringView path, BAN::RefPtr); + void initiate_disk_cache_drop(); void initiate_sync(bool should_block); private: @@ -37,6 +38,10 @@ namespace Kernel ThreadBlocker m_sync_done; ThreadBlocker m_sync_thread_blocker; volatile bool m_should_sync { false }; + + SpinLock m_disk_cache_lock; + ThreadBlocker m_disk_cache_thread_blocker; + BAN::Atomic m_should_drop_disk_cache { false }; }; } diff --git a/kernel/include/kernel/Storage/StorageDevice.h b/kernel/include/kernel/Storage/StorageDevice.h index ab48a63e1e..e87b2232b8 100644 --- a/kernel/include/kernel/Storage/StorageDevice.h +++ b/kernel/include/kernel/Storage/StorageDevice.h @@ -33,6 +33,7 @@ namespace Kernel BAN::Vector>& partitions() { return m_partitions; } const BAN::Vector>& partitions() const { return m_partitions; } + size_t drop_disk_cache(); BAN::ErrorOr sync_disk_cache(); virtual bool is_storage_device() const override { return true; } diff --git a/kernel/kernel/FS/DevFS/FileSystem.cpp b/kernel/kernel/FS/DevFS/FileSystem.cpp index 2644cfe2e9..c6b5cb0e4f 100644 --- a/kernel/kernel/FS/DevFS/FileSystem.cpp +++ b/kernel/kernel/FS/DevFS/FileSystem.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,36 @@ namespace Kernel )); MUST(Processor::scheduler().add_thread(updater_thread)); + auto* disk_cache_drop_thread = MUST(Thread::create_kernel( + [](void* _devfs) + { + auto* devfs = static_cast(_devfs); + + while (true) + { + { + SpinLockGuard guard(devfs->m_disk_cache_lock); + bool expected = true; + if (!devfs->m_should_drop_disk_cache.compare_exchange(expected, false)) + { + SpinLockGuardAsMutex smutex(guard); + devfs->m_disk_cache_thread_blocker.block_indefinite(&smutex); + continue; + } + } + + LockGuard _(devfs->m_device_lock); + + size_t pages_dropped = 0; + for (auto& device : devfs->m_devices) + if (device->is_storage_device()) + pages_dropped += static_cast(device.ptr())->drop_disk_cache(); + dprintln("Dropped {} pages from disk cache", pages_dropped); + } + }, s_instance + )); + MUST(Processor::scheduler().add_thread(disk_cache_drop_thread)); + auto* disk_sync_thread = MUST(Thread::create_kernel( [](void* _devfs) { @@ -94,6 +125,13 @@ namespace Kernel MUST(Processor::scheduler().add_thread(disk_sync_thread)); } + void DevFileSystem::initiate_disk_cache_drop() + { + SpinLockGuard _(m_disk_cache_lock); + m_should_drop_disk_cache = true; + m_disk_cache_thread_blocker.unblock(); + } + void DevFileSystem::initiate_sync(bool should_block) { LockGuard _(m_device_lock); diff --git a/kernel/kernel/Input/InputDevice.cpp b/kernel/kernel/Input/InputDevice.cpp index cce7361cf4..85adc5ca54 100644 --- a/kernel/kernel/Input/InputDevice.cpp +++ b/kernel/kernel/Input/InputDevice.cpp @@ -155,6 +155,9 @@ namespace Kernel case LibInput::keycode_function(1): Processor::toggle_should_print_cpu_load(); break; + case LibInput::keycode_function(11): + DevFileSystem::get().initiate_disk_cache_drop(); + break; case LibInput::keycode_function(12): Kernel::panic("Keyboard kernel panic :)"); break; diff --git a/kernel/kernel/Storage/StorageDevice.cpp b/kernel/kernel/Storage/StorageDevice.cpp index 95855f8e88..ec1a6a6650 100644 --- a/kernel/kernel/Storage/StorageDevice.cpp +++ b/kernel/kernel/Storage/StorageDevice.cpp @@ -216,6 +216,14 @@ namespace Kernel m_disk_cache.emplace(sector_size(), *this); } + size_t StorageDevice::drop_disk_cache() + { + LockGuard _(m_mutex); + if (m_disk_cache.has_value()) + return m_disk_cache->release_pages(-1); + return 0; + } + BAN::ErrorOr StorageDevice::sync_disk_cache() { LockGuard _(m_mutex);