Przeglądaj źródła

Kernel: Use an IntrusiveRedBlackTree for kernel regions

We were already using a non-intrusive RedBlackTree, and since the kernel
regions tree is non-owning, this is a trivial conversion that makes a
bunch of the tree operations infallible (by being allocation-free.) :^)
Andreas Kling 3 lat temu
rodzic
commit
df34f7b90b

+ 6 - 7
Kernel/Memory/MemoryManager.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -645,10 +645,10 @@ UNMAP_AFTER_INIT void MemoryManager::initialize(u32 cpu)
 Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress vaddr)
 {
     SpinlockLocker lock(s_mm_lock);
-    auto* region_ptr = MM.m_kernel_regions.find_largest_not_above(vaddr.get());
-    if (!region_ptr)
+    auto* region = MM.m_kernel_regions.find_largest_not_above(vaddr.get());
+    if (!region || !region->contains(vaddr))
         return nullptr;
-    return (*region_ptr)->contains(vaddr) ? *region_ptr : nullptr;
+    return region;
 }
 
 Region* MemoryManager::find_user_region_from_vaddr_no_lock(AddressSpace& space, VirtualAddress vaddr)
@@ -1111,7 +1111,7 @@ void MemoryManager::register_kernel_region(Region& region)
 {
     VERIFY(region.is_kernel());
     SpinlockLocker lock(s_mm_lock);
-    m_kernel_regions.insert(region.vaddr().get(), &region);
+    m_kernel_regions.insert(region.vaddr().get(), region);
 }
 
 void MemoryManager::unregister_kernel_region(Region& region)
@@ -1132,8 +1132,7 @@ void MemoryManager::dump_kernel_regions()
     dbgln("BEGIN{}         END{}        SIZE{}       ACCESS NAME",
         addr_padding, addr_padding, addr_padding);
     SpinlockLocker lock(s_mm_lock);
-    for (auto const* region_ptr : m_kernel_regions) {
-        auto const& region = *region_ptr;
+    for (auto const& region : m_kernel_regions) {
         dbgln("{:p} -- {:p} {:p} {:c}{:c}{:c}{:c}{:c}{:c} {}",
             region.vaddr().get(),
             region.vaddr().offset(region.size() - 1).get(),

+ 3 - 2
Kernel/Memory/MemoryManager.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -8,6 +8,7 @@
 
 #include <AK/Concepts.h>
 #include <AK/HashTable.h>
+#include <AK/IntrusiveRedBlackTree.h>
 #include <AK/NonnullOwnPtrVector.h>
 #include <AK/NonnullRefPtrVector.h>
 #include <Kernel/Forward.h>
@@ -293,7 +294,7 @@ private:
     PhysicalPageEntry* m_physical_page_entries { nullptr };
     size_t m_physical_page_entries_count { 0 };
 
-    RedBlackTree<FlatPtr, Region*> m_kernel_regions;
+    IntrusiveRedBlackTree<&Region::m_tree_node> m_kernel_regions;
 
     Vector<UsedMemoryRange> m_used_memory_ranges;
     Vector<PhysicalMemoryRange> m_physical_memory_ranges;

+ 4 - 3
Kernel/Memory/Region.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -8,6 +8,7 @@
 
 #include <AK/EnumBits.h>
 #include <AK/IntrusiveList.h>
+#include <AK/IntrusiveRedBlackTree.h>
 #include <AK/Weakable.h>
 #include <Kernel/Forward.h>
 #include <Kernel/KString.h>
@@ -219,11 +220,11 @@ private:
     bool m_stack : 1 { false };
     bool m_mmap : 1 { false };
     bool m_syscall_region : 1 { false };
-    IntrusiveListNode<Region> m_memory_manager_list_node;
+
+    IntrusiveRedBlackTreeNode<FlatPtr, Region, RawPtr<Region>> m_tree_node;
     IntrusiveListNode<Region> m_vmobject_list_node;
 
 public:
-    using ListInMemoryManager = IntrusiveList<&Region::m_memory_manager_list_node>;
     using ListInVMObject = IntrusiveList<&Region::m_vmobject_list_node>;
 };