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.
This commit is contained in:
Andreas Kling 2019-08-08 10:53:24 +02:00
parent a96d76fd90
commit 07425580a8
Notes: sideshowbarker 2024-07-19 12:49:19 +09:00
4 changed files with 14 additions and 8 deletions

View File

@ -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<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)
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)
callback(*region);
}

View File

@ -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(&region);
m_kernel_regions.append(&region);
else
m_user_regions.set(&region);
m_user_regions.append(&region);
}
void MemoryManager::unregister_region(Region& region)

View File

@ -143,8 +143,8 @@ private:
NonnullRefPtrVector<PhysicalRegion> m_user_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;

View File

@ -2,13 +2,15 @@
#include <AK/AKString.h>
#include <AK/Bitmap.h>
#include <AK/InlineLinkedList.h>
#include <Kernel/VM/PageDirectory.h>
#include <Kernel/VM/RangeAllocator.h>
class Inode;
class VMObject;
class Region : public RefCounted<Region> {
class Region : public RefCounted<Region>
, public InlineLinkedListNode<Region> {
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<VMObject>, size_t offset_in_vmo, const String&, u8 access, bool cow = false);