summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-12-29 12:45:58 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-29 12:45:58 +0100
commitc74cde918a5ef031d5f01c663212b1c909564cf4 (patch)
tree2f0b13a03c6477053d418c47ba8b9189bb7cd5d9 /Kernel
parent0d5e0e4cad512ebdcebc1c9a9171c412fcabbd3b (diff)
downloadserenity-c74cde918a5ef031d5f01c663212b1c909564cf4.zip
Kernel+SystemMonitor: Expose amount of per-process clean inode memory
This is memory that's loaded from an inode (file) but not modified in memory, so still identical to what's on disk. This kind of memory can be freed and reloaded transparently from disk if needed.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/ProcFS.cpp1
-rw-r--r--Kernel/Process.cpp16
-rw-r--r--Kernel/Process.h1
-rw-r--r--Kernel/VM/InodeVMObject.cpp10
-rw-r--r--Kernel/VM/InodeVMObject.h1
5 files changed, 29 insertions, 0 deletions
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp
index 00aacacfaf..a3ea6c78ae 100644
--- a/Kernel/FileSystem/ProcFS.cpp
+++ b/Kernel/FileSystem/ProcFS.cpp
@@ -754,6 +754,7 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
process_object.add("amount_virtual", (u32)process.amount_virtual());
process_object.add("amount_resident", (u32)process.amount_resident());
process_object.add("amount_dirty_private", (u32)process.amount_dirty_private());
+ process_object.add("amount_clean_inode", (u32)process.amount_clean_inode());
process_object.add("amount_shared", (u32)process.amount_shared());
process_object.add("amount_purgeable_volatile", (u32)process.amount_purgeable_volatile());
process_object.add("amount_purgeable_nonvolatile", (u32)process.amount_purgeable_nonvolatile());
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index dd7f6f1f71..91d870fd6d 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -2504,6 +2504,9 @@ void Process::die()
size_t Process::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;
for (auto& region : m_regions) {
if (!region.is_shared())
@@ -2512,6 +2515,19 @@ size_t Process::amount_dirty_private() const
return amount;
}
+size_t Process::amount_clean_inode() const
+{
+ HashTable<const InodeVMObject*> vmobjects;
+ 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 Process::amount_virtual() const
{
size_t amount = 0;
diff --git a/Kernel/Process.h b/Kernel/Process.h
index d4ad159dae..40fa865c15 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -272,6 +272,7 @@ public:
int number_of_open_file_descriptors() const;
int max_open_file_descriptors() const { return m_max_open_file_descriptors; }
+ size_t amount_clean_inode() const;
size_t amount_dirty_private() const;
size_t amount_virtual() const;
size_t amount_resident() const;
diff --git a/Kernel/VM/InodeVMObject.cpp b/Kernel/VM/InodeVMObject.cpp
index 5edc9b3c20..65c1177988 100644
--- a/Kernel/VM/InodeVMObject.cpp
+++ b/Kernel/VM/InodeVMObject.cpp
@@ -36,6 +36,16 @@ InodeVMObject::~InodeVMObject()
ASSERT(inode().vmobject() == this);
}
+size_t InodeVMObject::amount_clean() const
+{
+ size_t count = 0;
+ for (int i = 0; i < m_dirty_pages.size(); ++i) {
+ if (!m_dirty_pages.get(i) && m_physical_pages[i])
+ ++count;
+ }
+ return count * PAGE_SIZE;
+}
+
size_t InodeVMObject::amount_dirty() const
{
size_t count = 0;
diff --git a/Kernel/VM/InodeVMObject.h b/Kernel/VM/InodeVMObject.h
index 56e8b344d6..e4e44cff7f 100644
--- a/Kernel/VM/InodeVMObject.h
+++ b/Kernel/VM/InodeVMObject.h
@@ -17,6 +17,7 @@ public:
void inode_size_changed(Badge<Inode>, size_t old_size, size_t new_size);
size_t amount_dirty() const;
+ size_t amount_clean() const;
private:
explicit InodeVMObject(Inode&);