summaryrefslogtreecommitdiff
path: root/Kernel/VM/MemoryManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/VM/MemoryManager.cpp')
-rw-r--r--Kernel/VM/MemoryManager.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp
index db2a55e0f7..8f44ddc25a 100644
--- a/Kernel/VM/MemoryManager.cpp
+++ b/Kernel/VM/MemoryManager.cpp
@@ -9,6 +9,7 @@
#include <Kernel/VM/AnonymousVMObject.h>
#include <Kernel/VM/InodeVMObject.h>
#include <Kernel/VM/MemoryManager.h>
+#include <Kernel/VM/PurgeableVMObject.h>
//#define MM_DEBUG
//#define PAGE_FAULT_DEBUG
@@ -424,9 +425,25 @@ RefPtr<PhysicalPage> MemoryManager::allocate_user_physical_page(ShouldZeroFill s
kprintf("MM: no user physical regions available (?)\n");
}
- kprintf("MM: no user physical pages available\n");
- ASSERT_NOT_REACHED();
- return {};
+ for_each_vmobject([&](auto& vmobject) {
+ if (vmobject.is_purgeable()) {
+ auto& purgeable_vmobject = static_cast<PurgeableVMObject&>(vmobject);
+ int purged_page_count = purgeable_vmobject.purge_with_interrupts_disabled({});
+ if (purged_page_count) {
+ kprintf("MM: Purge saved the day! Purged %d pages from PurgeableVMObject{%p}\n", purged_page_count, &purgeable_vmobject);
+ page = find_free_user_physical_page();
+ ASSERT(page);
+ return IterationDecision::Break;
+ }
+ }
+ return IterationDecision::Continue;
+ });
+
+ if (!page) {
+ kprintf("MM: no user physical pages available\n");
+ ASSERT_NOT_REACHED();
+ return {};
+ }
}
#ifdef MM_DEBUG