From 7704e3c5c0c22c285e65341720cf64b29a61f9dc Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 20 May 2026 00:16:56 +0300 Subject: [PATCH] Kernel: Implement per cpu fast pages Basically every fast page usage should be converted into this but I'll do them one by one when they show up in profiles --- kernel/arch/i686/PageTable.cpp | 12 ++++++++++-- kernel/arch/x86_64/PageTable.cpp | 12 ++++++++++-- kernel/include/kernel/Memory/PageTable.h | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/kernel/arch/i686/PageTable.cpp b/kernel/arch/i686/PageTable.cpp index 90013052..4ef9ce02 100644 --- a/kernel/arch/i686/PageTable.cpp +++ b/kernel/arch/i686/PageTable.cpp @@ -258,7 +258,11 @@ namespace Kernel ASSERT(index < 512); ASSERT(s_fast_page_pt); - ASSERT(s_fast_page_lock.current_processor_has_lock()); + + if (index < reserved_fast_pages) + ASSERT(s_fast_page_lock.current_processor_has_lock()); + else + ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled); ASSERT(!(s_fast_page_pt[index] & Flags::Present)); s_fast_page_pt[index] = paddr | Flags::ReadWrite | Flags::Present; @@ -272,7 +276,11 @@ namespace Kernel { ASSERT(index < 512); ASSERT(s_fast_page_pt); - ASSERT(s_fast_page_lock.current_processor_has_lock()); + + if (index < reserved_fast_pages) + ASSERT(s_fast_page_lock.current_processor_has_lock()); + else + ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled); ASSERT((s_fast_page_pt[index] & Flags::Present)); s_fast_page_pt[index] = 0; diff --git a/kernel/arch/x86_64/PageTable.cpp b/kernel/arch/x86_64/PageTable.cpp index fa57f1c8..dd410d23 100644 --- a/kernel/arch/x86_64/PageTable.cpp +++ b/kernel/arch/x86_64/PageTable.cpp @@ -382,7 +382,11 @@ namespace Kernel ASSERT(index < 512); ASSERT(s_fast_page_pt); - ASSERT(s_fast_page_lock.current_processor_has_lock()); + + if (index < reserved_fast_pages) + ASSERT(s_fast_page_lock.current_processor_has_lock()); + else + ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled); ASSERT(!(s_fast_page_pt[index] & Flags::Present)); s_fast_page_pt[index] = paddr | Flags::ReadWrite | Flags::Present; @@ -396,7 +400,11 @@ namespace Kernel { ASSERT(index < 512); ASSERT(s_fast_page_pt); - ASSERT(s_fast_page_lock.current_processor_has_lock()); + + if (index < reserved_fast_pages) + ASSERT(s_fast_page_lock.current_processor_has_lock()); + else + ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled); ASSERT((s_fast_page_pt[index] & Flags::Present)); s_fast_page_pt[index] = 0; diff --git a/kernel/include/kernel/Memory/PageTable.h b/kernel/include/kernel/Memory/PageTable.h index 146c8985..68930860 100644 --- a/kernel/include/kernel/Memory/PageTable.h +++ b/kernel/include/kernel/Memory/PageTable.h @@ -14,6 +14,12 @@ namespace Kernel requires BAN::is_same_v; }; + template + concept with_per_cpu_fast_page_callback = requires(F func, void* addr) + { + requires BAN::is_same_v; + }; + template concept with_fast_page_callback_error = requires(F func) { @@ -47,6 +53,8 @@ namespace Kernel static constexpr bool full_tlb_flush_threshold = 32; + static constexpr size_t reserved_fast_pages = 0x10; + public: static void initialize_fast_page(); static void initialize_and_load(); @@ -74,6 +82,18 @@ namespace Kernel unmap_fast_page(); } + template + static void with_per_cpu_fast_page(paddr_t paddr, F callback) + { + const auto state = Processor::get_interrupt_state(); + Processor::set_interrupt_state(InterruptState::Disabled); + const size_t index = Processor::current_index() + reserved_fast_pages; + void* addr = map_fast_page(index, paddr); + callback(addr); + unmap_fast_page(index); + Processor::set_interrupt_state(state); + } + template static BAN::ErrorOr with_fast_page(paddr_t paddr, F callback) {