From 4f5f84bb5b547454dbce2f149040cbabfbd52200 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 20 May 2026 01:08:08 +0300 Subject: [PATCH] Kernel: Speed up mmap address space reservation by a lot Instead of scanning the page table for free range, we not use the process's mapped regions to find a slot. This speeds up mmap by a lot! --- kernel/include/kernel/Process.h | 2 ++ kernel/kernel/Process.cpp | 58 ++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index f9c4fd4b..60b85a28 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -278,6 +278,8 @@ namespace Kernel // You must hold reader end of m_mapped_region_lock when calling this. size_t find_mapped_region(vaddr_t) const; + BAN::ErrorOr find_free_address_range(size_t size); + BAN::ErrorOr find_file(int fd, const char* path, int flags) const; BAN::ErrorOr find_parent_file(int fd, const char* path, int flags) const; BAN::ErrorOr find_relative_parent(int fd, const char* path) const; diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index f2f29f66..575ea665 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -483,6 +483,26 @@ namespace Kernel return l; } + BAN::ErrorOr Process::find_free_address_range(size_t size) + { + if (auto rem = size % PAGE_SIZE) + size += PAGE_SIZE - rem; + + vaddr_t vaddr = m_shared_page_vaddr ? m_shared_page_vaddr + PAGE_SIZE : 0x400000; + for (size_t i = find_mapped_region(vaddr); i < m_mapped_regions.size(); i++) + { + const auto& region = m_mapped_regions[i]; + if (!region->overlaps(vaddr, size)) + return AddressRange { vaddr, vaddr + size }; + + vaddr = region->vaddr() + region->size(); + if (auto rem = vaddr % PAGE_SIZE) + vaddr += PAGE_SIZE - rem; + } + + return BAN::Error::from_errno(ENOMEM); + } + size_t Process::proc_meminfo(off_t offset, BAN::ByteSpan buffer) const { ASSERT(offset >= 0); @@ -2470,7 +2490,7 @@ namespace Kernel RWLockWRGuard _(m_memory_region_lock); - AddressRange address_range { .start = 0x400000, .end = USERSPACE_END }; + AddressRange address_range; if (args.flags & (MAP_FIXED | MAP_FIXED_NOREPLACE)) { const vaddr_t vaddr = reinterpret_cast(args.addr); @@ -2509,22 +2529,30 @@ namespace Kernel } } } - else if (const vaddr_t vaddr = reinterpret_cast(args.addr); vaddr == 0) - ; - else if (vaddr % PAGE_SIZE) - ; - else if (!PageTable::is_valid_pointer(vaddr)) - ; - else if (!PageTable::is_valid_pointer(vaddr + args.len)) - ; - else if (!page_table().is_range_free(vaddr, args.len)) - ; else { - address_range = { - .start = vaddr, - .end = vaddr + args.len, - }; + bool use_address_hint = false; + + const vaddr_t vaddr = reinterpret_cast(args.addr); + if (vaddr == 0 || vaddr % PAGE_SIZE) + ; + else if (!PageTable::is_valid_pointer(vaddr)) + ; + else if (!PageTable::is_valid_pointer(vaddr + args.len)) + ; + else if (!page_table().is_range_free(vaddr, args.len)) + ; + else + { + use_address_hint = true; + address_range = { + .start = vaddr, + .end = vaddr + args.len, + }; + } + + if (!use_address_hint) + address_range = TRY(find_free_address_range(args.len)); } if (args.flags & MAP_ANONYMOUS)