From a819eb501664163494053d58e00ebe75893d607b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 3 Mar 2021 22:45:18 +0100 Subject: [PATCH] Kernel: Skip TLB flushes while cloning regions in sys$fork() Since we know for sure that the virtual memory regions in the new process being created are not being used on any CPU, there's no need to do TLB flushes for every mapped page. --- Kernel/Syscalls/fork.cpp | 2 +- Kernel/VM/Region.cpp | 5 +++-- Kernel/VM/Region.h | 7 ++++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index 4b462bb6725..054510bbaa2 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -89,7 +89,7 @@ KResultOr Process::sys$fork(RegisterState& regs) } auto& child_region = child->space().add_region(region_clone.release_nonnull()); - child_region.map(child->space().page_directory()); + child_region.map(child->space().page_directory(), ShouldFlushTLB::No); if (®ion == m_master_tls_region.unsafe_ptr()) child->m_master_tls_region = child_region; diff --git a/Kernel/VM/Region.cpp b/Kernel/VM/Region.cpp index 1b8ef0d8ee7..403888d6d4f 100644 --- a/Kernel/VM/Region.cpp +++ b/Kernel/VM/Region.cpp @@ -385,7 +385,7 @@ void Region::set_page_directory(PageDirectory& page_directory) m_page_directory = page_directory; } -bool Region::map(PageDirectory& page_directory) +bool Region::map(PageDirectory& page_directory, ShouldFlushTLB should_flush_tlb) { ScopedSpinLock lock(s_mm_lock); ScopedSpinLock page_lock(page_directory.get_lock()); @@ -403,7 +403,8 @@ bool Region::map(PageDirectory& page_directory) ++page_index; } if (page_index > 0) { - MM.flush_tlb(m_page_directory, vaddr(), page_index); + if (should_flush_tlb == ShouldFlushTLB::Yes) + MM.flush_tlb(m_page_directory, vaddr(), page_index); return page_index == page_count(); } return false; diff --git a/Kernel/VM/Region.h b/Kernel/VM/Region.h index 5e2308ec577..2c93d2bb1b7 100644 --- a/Kernel/VM/Region.h +++ b/Kernel/VM/Region.h @@ -42,6 +42,11 @@ namespace Kernel { class Inode; class VMObject; +enum class ShouldFlushTLB { + No, + Yes, +}; + class Region final : public InlineLinkedListNode , public Weakable @@ -215,7 +220,7 @@ public: void set_executable(bool b) { set_access_bit(Access::Execute, b); } void set_page_directory(PageDirectory&); - bool map(PageDirectory&); + bool map(PageDirectory&, ShouldFlushTLB = ShouldFlushTLB::Yes); enum class ShouldDeallocateVirtualMemoryRange { No, Yes,