1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 23:47:45 +00:00

Kernel+SystemMonitor: Add fault counters

This patch adds three separate per-process fault counters:

- Inode faults

    An inode fault happens when we've memory-mapped a file from disk
    and we end up having to load 1 page (4KB) of the file into memory.

- Zero faults

    Memory returned by mmap() is lazily zeroed out. Every time we have
    to zero out 1 page, we count a zero fault.

- CoW faults

    VM objects can be shared by multiple mappings that make their own
    unique copy iff they want to modify it. The typical reason here is
    memory shared between a parent and child process.
This commit is contained in:
Andreas Kling 2019-10-02 14:13:49 +02:00
parent c33ac7f170
commit 35138437ef
7 changed files with 62 additions and 0 deletions

View file

@ -685,6 +685,9 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
process_object.add("ticks", process.main_thread().ticks());
process_object.add("priority", to_string(process.priority()));
process_object.add("syscall_count", process.syscall_count());
process_object.add("inode_faults", process.inode_faults());
process_object.add("zero_faults", process.zero_faults());
process_object.add("cow_faults", process.cow_faults());
process_object.add("icon_id", process.icon_id());
};
build_process(*Scheduler::colonel());

View file

@ -291,6 +291,12 @@ public:
unsigned syscall_count() const { return m_syscall_count; }
void did_syscall() { ++m_syscall_count; }
unsigned inode_faults() const { return m_inode_faults; }
void did_inode_fault() { ++m_inode_faults; }
unsigned zero_faults() const { return m_zero_faults; }
void did_zero_fault() { ++m_zero_faults; }
unsigned cow_faults() const { return m_cow_faults; }
void did_cow_fault() { ++m_cow_faults; }
const ELFLoader* elf_loader() const { return m_elf_loader.ptr(); }
@ -369,6 +375,9 @@ private:
int m_next_tid { 0 };
unsigned m_syscall_count { 0 };
unsigned m_inode_faults { 0 };
unsigned m_zero_faults { 0 };
unsigned m_cow_faults { 0 };
RefPtr<ProcessTracer> m_tracer;
OwnPtr<ELFLoader> m_elf_loader;

View file

@ -296,6 +296,7 @@ bool MemoryManager::zero_page(Region& region, unsigned page_index_in_region)
sti();
LOCKER(vmo.m_paging_lock);
cli();
if (!vmo_page.is_null()) {
#ifdef PAGE_FAULT_DEBUG
dbgprintf("MM: zero_page() but page already present. Fine with me!\n");
@ -303,6 +304,10 @@ bool MemoryManager::zero_page(Region& region, unsigned page_index_in_region)
remap_region_page(region, page_index_in_region);
return true;
}
if (current)
current->process().did_zero_fault();
auto physical_page = allocate_user_physical_page(ShouldZeroFill::Yes);
#ifdef PAGE_FAULT_DEBUG
dbgprintf(" >> ZERO P%p\n", physical_page->paddr().get());
@ -325,6 +330,9 @@ bool MemoryManager::copy_on_write(Region& region, unsigned page_index_in_region)
return true;
}
if (current)
current->process().did_cow_fault();
#ifdef PAGE_FAULT_DEBUG
dbgprintf(" >> It's a COW page and it's time to COW!\n");
#endif
@ -367,6 +375,9 @@ bool MemoryManager::page_in_from_inode(Region& region, unsigned page_index_in_re
return true;
}
if (current)
current->process().did_inode_fault();
#ifdef MM_DEBUG
dbgprintf("MM: page_in_from_inode ready to read from inode\n");
#endif