summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-08-14 21:46:08 +0200
committerAndreas Kling <kling@serenityos.org>2022-08-14 23:33:28 +0200
commit9e9924115f68c0cf7c24697510ed07b726529983 (patch)
treea0a58443e09223413801e2e3f205cf232dcc2a5c /Kernel
parent92556e07d3a41b9dd31e557f9d9f710f4db963f4 (diff)
downloadserenity-9e9924115f68c0cf7c24697510ed07b726529983.zip
Kernel: Release some clean file-backed memory when starved for pages
Until now, our only backup plan when running out of physical pages was to try and purge volatile memory. If that didn't work out, we just hung userspace out to dry with an ENOMEM. This patch improves the situation by also considering clean, file-backed pages (that we could page back in from disk). This could be better in many ways, but it already allows us to boot to WindowServer with 256 MiB of RAM. :^)
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Memory/MemoryManager.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/Kernel/Memory/MemoryManager.cpp b/Kernel/Memory/MemoryManager.cpp
index fda5530b02..0b312fa4a6 100644
--- a/Kernel/Memory/MemoryManager.cpp
+++ b/Kernel/Memory/MemoryManager.cpp
@@ -929,6 +929,20 @@ ErrorOr<NonnullRefPtr<PhysicalPage>> MemoryManager::allocate_physical_page(Shoul
}
return IterationDecision::Continue;
});
+ // Second, we look for a file-backed VMObject with clean pages.
+ for_each_vmobject([&](auto& vmobject) {
+ if (!vmobject.is_inode())
+ return IterationDecision::Continue;
+ auto& inode_vmobject = static_cast<InodeVMObject&>(vmobject);
+ // FIXME: It seems excessive to release *all* clean pages from the inode when we only need one.
+ if (auto released_page_count = inode_vmobject.release_all_clean_pages()) {
+ dbgln("MM: Clean inode release saved the day! Released {} pages from InodeVMObject", released_page_count);
+ page = find_free_physical_page(false);
+ VERIFY(page);
+ return IterationDecision::Break;
+ }
+ return IterationDecision::Continue;
+ });
if (!page) {
dmesgln("MM: no physical pages available");
return ENOMEM;