summaryrefslogtreecommitdiff
path: root/Kernel/VM
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-02-08 22:11:10 +0100
committerAndreas Kling <kling@serenityos.org>2021-02-08 22:23:29 +0100
commit8bda30edd28be7b292cd18b69abe6490e66d7d0b (patch)
tree5dbe939b7dff7b525c35bd766027968144c15c7d /Kernel/VM
parentb1c9f93fa32fba16116c4764c5152f85ab427394 (diff)
downloadserenity-8bda30edd28be7b292cd18b69abe6490e66d7d0b.zip
Kernel: Move memory statistics helpers from Process to Space
Diffstat (limited to 'Kernel/VM')
-rw-r--r--Kernel/VM/Space.cpp88
-rw-r--r--Kernel/VM/Space.h8
2 files changed, 96 insertions, 0 deletions
diff --git a/Kernel/VM/Space.cpp b/Kernel/VM/Space.cpp
index bbee739db1..16ef065fba 100644
--- a/Kernel/VM/Space.cpp
+++ b/Kernel/VM/Space.cpp
@@ -28,6 +28,7 @@
#include <Kernel/Process.h>
#include <Kernel/SpinLock.h>
#include <Kernel/VM/AnonymousVMObject.h>
+#include <Kernel/VM/InodeVMObject.h>
#include <Kernel/VM/MemoryManager.h>
#include <Kernel/VM/Space.h>
@@ -219,4 +220,91 @@ void Space::remove_all_regions(Badge<Process>)
m_regions.clear();
}
+size_t Space::amount_dirty_private() const
+{
+ // FIXME: This gets a bit more complicated for Regions sharing the same underlying VMObject.
+ // The main issue I'm thinking of is when the VMObject has physical pages that none of the Regions are mapping.
+ // That's probably a situation that needs to be looked at in general.
+ size_t amount = 0;
+ ScopedSpinLock lock(m_lock);
+ for (auto& region : m_regions) {
+ if (!region.is_shared())
+ amount += region.amount_dirty();
+ }
+ return amount;
+}
+
+size_t Space::amount_clean_inode() const
+{
+ HashTable<const InodeVMObject*> vmobjects;
+ {
+ ScopedSpinLock lock(m_lock);
+ for (auto& region : m_regions) {
+ if (region.vmobject().is_inode())
+ vmobjects.set(&static_cast<const InodeVMObject&>(region.vmobject()));
+ }
+ }
+ size_t amount = 0;
+ for (auto& vmobject : vmobjects)
+ amount += vmobject->amount_clean();
+ return amount;
+}
+
+size_t Space::amount_virtual() const
+{
+ size_t amount = 0;
+ ScopedSpinLock lock(m_lock);
+ for (auto& region : m_regions) {
+ amount += region.size();
+ }
+ return amount;
+}
+
+size_t Space::amount_resident() const
+{
+ // FIXME: This will double count if multiple regions use the same physical page.
+ size_t amount = 0;
+ ScopedSpinLock lock(m_lock);
+ for (auto& region : m_regions) {
+ amount += region.amount_resident();
+ }
+ return amount;
+}
+
+size_t Space::amount_shared() const
+{
+ // FIXME: This will double count if multiple regions use the same physical page.
+ // FIXME: It doesn't work at the moment, since it relies on PhysicalPage ref counts,
+ // and each PhysicalPage is only reffed by its VMObject. This needs to be refactored
+ // so that every Region contributes +1 ref to each of its PhysicalPages.
+ size_t amount = 0;
+ ScopedSpinLock lock(m_lock);
+ for (auto& region : m_regions) {
+ amount += region.amount_shared();
+ }
+ return amount;
+}
+
+size_t Space::amount_purgeable_volatile() const
+{
+ size_t amount = 0;
+ ScopedSpinLock lock(m_lock);
+ for (auto& region : m_regions) {
+ if (region.vmobject().is_anonymous() && static_cast<const AnonymousVMObject&>(region.vmobject()).is_any_volatile())
+ amount += region.amount_resident();
+ }
+ return amount;
+}
+
+size_t Space::amount_purgeable_nonvolatile() const
+{
+ size_t amount = 0;
+ ScopedSpinLock lock(m_lock);
+ for (auto& region : m_regions) {
+ if (region.vmobject().is_anonymous() && !static_cast<const AnonymousVMObject&>(region.vmobject()).is_any_volatile())
+ amount += region.amount_resident();
+ }
+ return amount;
+}
+
}
diff --git a/Kernel/VM/Space.h b/Kernel/VM/Space.h
index 4e4a76dc13..5f376ec389 100644
--- a/Kernel/VM/Space.h
+++ b/Kernel/VM/Space.h
@@ -70,6 +70,14 @@ public:
SpinLock<u32>& get_lock() const { return m_lock; }
+ size_t amount_clean_inode() const;
+ size_t amount_dirty_private() const;
+ size_t amount_virtual() const;
+ size_t amount_resident() const;
+ size_t amount_shared() const;
+ size_t amount_purgeable_volatile() const;
+ size_t amount_purgeable_nonvolatile() const;
+
private:
Space(Process&, NonnullRefPtr<PageDirectory>);