瀏覽代碼

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.
Andreas Kling 6 年之前
父節點
當前提交
07425580a8
共有 4 個文件被更改,包括 14 次插入8 次删除
  1. 2 2
      Kernel/VM/InodeVMObject.cpp
  2. 3 3
      Kernel/VM/MemoryManager.cpp
  3. 2 2
      Kernel/VM/MemoryManager.h
  4. 7 1
      Kernel/VM/Region.h

+ 2 - 2
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.
     // 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<Region*> with all of his mappers?
     //        Perhaps VMObject could have a Vector<Region*> 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 (&region->vmo() == this)
         if (&region->vmo() == this)
             callback(*region);
             callback(*region);
     }
     }
-    for (auto* region : MM.m_kernel_regions) {
+    for (auto* region = MM.m_kernel_regions.head(); region; region = region->next()) {
         if (&region->vmo() == this)
         if (&region->vmo() == this)
             callback(*region);
             callback(*region);
     }
     }

+ 3 - 3
Kernel/VM/MemoryManager.cpp

@@ -246,7 +246,7 @@ Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress vaddr)
 {
 {
     if (vaddr.get() < 0xc0000000)
     if (vaddr.get() < 0xc0000000)
         return nullptr;
         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))
         if (region->contains(vaddr))
             return region;
             return region;
     }
     }
@@ -766,9 +766,9 @@ void MemoryManager::register_region(Region& region)
 {
 {
     InterruptDisabler disabler;
     InterruptDisabler disabler;
     if (region.vaddr().get() >= 0xc0000000)
     if (region.vaddr().get() >= 0xc0000000)
-        m_kernel_regions.set(&region);
+        m_kernel_regions.append(&region);
     else
     else
-        m_user_regions.set(&region);
+        m_user_regions.append(&region);
 }
 }
 
 
 void MemoryManager::unregister_region(Region& region)
 void MemoryManager::unregister_region(Region& region)

+ 2 - 2
Kernel/VM/MemoryManager.h

@@ -143,8 +143,8 @@ private:
     NonnullRefPtrVector<PhysicalRegion> m_user_physical_regions;
     NonnullRefPtrVector<PhysicalRegion> m_user_physical_regions;
     NonnullRefPtrVector<PhysicalRegion> m_super_physical_regions;
     NonnullRefPtrVector<PhysicalRegion> m_super_physical_regions;
 
 
-    HashTable<Region*> m_user_regions;
-    HashTable<Region*> m_kernel_regions;
+    InlineLinkedList<Region> m_user_regions;
+    InlineLinkedList<Region> m_kernel_regions;
 
 
     InlineLinkedList<VMObject> m_vmobjects;
     InlineLinkedList<VMObject> m_vmobjects;
 
 

+ 7 - 1
Kernel/VM/Region.h

@@ -2,13 +2,15 @@
 
 
 #include <AK/AKString.h>
 #include <AK/AKString.h>
 #include <AK/Bitmap.h>
 #include <AK/Bitmap.h>
+#include <AK/InlineLinkedList.h>
 #include <Kernel/VM/PageDirectory.h>
 #include <Kernel/VM/PageDirectory.h>
 #include <Kernel/VM/RangeAllocator.h>
 #include <Kernel/VM/RangeAllocator.h>
 
 
 class Inode;
 class Inode;
 class VMObject;
 class VMObject;
 
 
-class Region : public RefCounted<Region> {
+class Region : public RefCounted<Region>
+    , public InlineLinkedListNode<Region> {
     friend class MemoryManager;
     friend class MemoryManager;
 
 
 public:
 public:
@@ -100,6 +102,10 @@ public:
             m_access &= ~Access::Write;
             m_access &= ~Access::Write;
     }
     }
 
 
+    // For InlineLinkedListNode
+    Region* m_next { nullptr };
+    Region* m_prev { nullptr };
+
 private:
 private:
     Region(const Range&, const String&, u8 access, bool cow = false);
     Region(const Range&, const String&, u8 access, bool cow = false);
     Region(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmo, const String&, u8 access, bool cow = false);
     Region(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmo, const String&, u8 access, bool cow = false);