1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 20:28:11 +00:00

Kernel: Simplify VMObject locking & page fault handlers

This patch greatly simplifies VMObject locking by doing two things:

1. Giving VMObject an IntrusiveList of all its mapping Region objects.
2. Removing VMObject::m_paging_lock in favor of VMObject::m_lock

Before (1), VMObject::for_each_region() was forced to acquire the
global MM lock (since it worked by walking MemoryManager's list of
all regions and checking for regions that pointed to itself.)

With each VMObject having its own list of Regions, VMObject's own
m_lock is all we need.

Before (2), page fault handlers used a separate mutex for preventing
overlapping work. This design required multiple temporary unlocks
and was generally extremely hard to reason about.

Instead, page fault handlers now use VMObject's own m_lock as well.
This commit is contained in:
Andreas Kling 2021-07-23 02:40:16 +02:00
parent 64babcaa83
commit 082ed6f417
10 changed files with 116 additions and 155 deletions

View file

@ -175,6 +175,7 @@ public:
template<IteratorFunction<VMObject&> Callback>
static void for_each_vmobject(Callback callback)
{
ScopedSpinLock locker(s_mm_lock);
for (auto& vmobject : MM.m_vmobjects) {
if (callback(vmobject) == IterationDecision::Break)
break;
@ -255,8 +256,8 @@ private:
PhysicalPageEntry* m_physical_page_entries { nullptr };
size_t m_physical_page_entries_count { 0 };
Region::List m_user_regions;
Region::List m_kernel_regions;
Region::ListInMemoryManager m_user_regions;
Region::ListInMemoryManager m_kernel_regions;
Vector<UsedMemoryRange> m_used_memory_ranges;
Vector<PhysicalMemoryRange> m_physical_memory_ranges;
Vector<ContiguousReservedMemoryRange> m_reserved_memory_ranges;
@ -264,22 +265,6 @@ private:
VMObject::List m_vmobjects;
};
template<typename Callback>
void VMObject::for_each_region(Callback callback)
{
ScopedSpinLock lock(s_mm_lock);
// 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) {
if (&region.vmobject() == this)
callback(region);
}
for (auto& region : MM.m_kernel_regions) {
if (&region.vmobject() == this)
callback(region);
}
}
inline bool is_user_address(VirtualAddress vaddr)
{
return vaddr.get() < USER_RANGE_CEILING;