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.
This commit is contained in:
Andreas Kling 2021-03-03 22:45:18 +01:00
parent 8fd69e9e56
commit a819eb5016
Notes: sideshowbarker 2024-07-18 21:44:38 +09:00
3 changed files with 10 additions and 4 deletions

View file

@ -89,7 +89,7 @@ KResultOr<pid_t> 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 (&region == m_master_tls_region.unsafe_ptr())
child->m_master_tls_region = child_region;

View file

@ -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;

View file

@ -42,6 +42,11 @@ namespace Kernel {
class Inode;
class VMObject;
enum class ShouldFlushTLB {
No,
Yes,
};
class Region final
: public InlineLinkedListNode<Region>
, public Weakable<Region>
@ -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,