From 07425580a8e293e4fcadf3fc3957f961a8aa8d30 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 8 Aug 2019 10:53:24 +0200 Subject: [PATCH] Kernel: Put all Regions on InlineLinkedLists (separated by user/kernel) Remove the global hash tables and replace them with InlineLinkedLists. This significantly reduces the kernel heap pressure from doing many small mmap()'s. --- Kernel/VM/InodeVMObject.cpp | 4 ++-- Kernel/VM/MemoryManager.cpp | 6 +++--- Kernel/VM/MemoryManager.h | 4 ++-- Kernel/VM/Region.h | 8 +++++++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Kernel/VM/InodeVMObject.cpp b/Kernel/VM/InodeVMObject.cpp index 29ef9c957ae..9b76008aba7 100644 --- a/Kernel/VM/InodeVMObject.cpp +++ b/Kernel/VM/InodeVMObject.cpp @@ -110,11 +110,11 @@ void VMObject::for_each_region(Callback callback) { // FIXME: Figure out a better data structure so we don't have to walk every single region every time an inode changes. // Perhaps VMObject could have a Vector with all of his mappers? - for (auto* region : MM.m_user_regions) { + for (auto* region = MM.m_user_regions.head(); region; region = region->next()) { if (®ion->vmo() == this) callback(*region); } - for (auto* region : MM.m_kernel_regions) { + for (auto* region = MM.m_kernel_regions.head(); region; region = region->next()) { if (®ion->vmo() == this) callback(*region); } diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 143dd6c495c..186ec08fbe8 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -246,7 +246,7 @@ Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress vaddr) { if (vaddr.get() < 0xc0000000) return nullptr; - for (auto& region : MM.m_kernel_regions) { + for (auto* region = MM.m_kernel_regions.head(); region; region = region->next()) { if (region->contains(vaddr)) return region; } @@ -766,9 +766,9 @@ void MemoryManager::register_region(Region& region) { InterruptDisabler disabler; if (region.vaddr().get() >= 0xc0000000) - m_kernel_regions.set(®ion); + m_kernel_regions.append(®ion); else - m_user_regions.set(®ion); + m_user_regions.append(®ion); } void MemoryManager::unregister_region(Region& region) diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h index e36043bcc8b..ab8f32c1945 100644 --- a/Kernel/VM/MemoryManager.h +++ b/Kernel/VM/MemoryManager.h @@ -143,8 +143,8 @@ private: NonnullRefPtrVector m_user_physical_regions; NonnullRefPtrVector m_super_physical_regions; - HashTable m_user_regions; - HashTable m_kernel_regions; + InlineLinkedList m_user_regions; + InlineLinkedList m_kernel_regions; InlineLinkedList m_vmobjects; diff --git a/Kernel/VM/Region.h b/Kernel/VM/Region.h index 32a24f293a6..32e02193fe0 100644 --- a/Kernel/VM/Region.h +++ b/Kernel/VM/Region.h @@ -2,13 +2,15 @@ #include #include +#include #include #include class Inode; class VMObject; -class Region : public RefCounted { +class Region : public RefCounted + , public InlineLinkedListNode { friend class MemoryManager; public: @@ -100,6 +102,10 @@ public: m_access &= ~Access::Write; } + // For InlineLinkedListNode + Region* m_next { nullptr }; + Region* m_prev { nullptr }; + private: Region(const Range&, const String&, u8 access, bool cow = false); Region(const Range&, NonnullRefPtr, size_t offset_in_vmo, const String&, u8 access, bool cow = false);