summaryrefslogtreecommitdiff
path: root/Kernel/Memory
diff options
context:
space:
mode:
authordylanbobb <dylan.bobb@hotmail.com>2022-08-14 23:05:42 -0400
committerAndreas Kling <kling@serenityos.org>2022-08-16 01:13:17 +0200
commit09d0fae2c6d267cce4d4a757988f5c889aa70531 (patch)
tree85b3c4fd726fd88ec667043ee74223215d1d3230 /Kernel/Memory
parent072dde93878cf61c3d8020c29752310c66786bd9 (diff)
downloadserenity-09d0fae2c6d267cce4d4a757988f5c889aa70531.zip
Kernel: Allow release of a specific amount of of clean pages
Previously, we could only release *all* clean pages. This patch makes it possible to release a specific amount of clean pages. If the attempted number of pages to release is more than the amount of clean pages, all clean pages will be released.
Diffstat (limited to 'Kernel/Memory')
-rw-r--r--Kernel/Memory/InodeVMObject.cpp19
-rw-r--r--Kernel/Memory/InodeVMObject.h1
2 files changed, 20 insertions, 0 deletions
diff --git a/Kernel/Memory/InodeVMObject.cpp b/Kernel/Memory/InodeVMObject.cpp
index 77cacf7e53..3ef5075866 100644
--- a/Kernel/Memory/InodeVMObject.cpp
+++ b/Kernel/Memory/InodeVMObject.cpp
@@ -67,6 +67,25 @@ int InodeVMObject::release_all_clean_pages()
return count;
}
+int InodeVMObject::try_release_clean_pages(int page_amount)
+{
+ SpinlockLocker locker(m_lock);
+
+ int count = 0;
+ for (size_t i = 0; i < page_count() && count < page_amount; ++i) {
+ if (!m_dirty_pages.get(i) && m_physical_pages[i]) {
+ m_physical_pages[i] = nullptr;
+ ++count;
+ }
+ }
+ if (count) {
+ for_each_region([](auto& region) {
+ region.remap();
+ });
+ }
+ return count;
+}
+
u32 InodeVMObject::writable_mappings() const
{
u32 count = 0;
diff --git a/Kernel/Memory/InodeVMObject.h b/Kernel/Memory/InodeVMObject.h
index 6f9500c933..1f09c5b263 100644
--- a/Kernel/Memory/InodeVMObject.h
+++ b/Kernel/Memory/InodeVMObject.h
@@ -23,6 +23,7 @@ public:
size_t amount_clean() const;
int release_all_clean_pages();
+ int try_release_clean_pages(int page_amount);
u32 writable_mappings() const;
u32 executable_mappings() const;