From 797ca65c66b889a935ec611914d9f00279ce11a2 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 30 Sep 2023 22:11:45 +0300 Subject: [PATCH] Kernel: Add physical memory info to /proc/{pid}/meminfo --- LibELF/LibELF/LoadableELF.cpp | 2 ++ LibELF/include/LibELF/LoadableELF.h | 2 ++ kernel/include/kernel/Memory/FileBackedRegion.h | 5 +++-- kernel/include/kernel/Memory/MemoryBackedRegion.h | 4 +++- kernel/include/kernel/Memory/MemoryRegion.h | 6 +++++- kernel/include/kernel/Thread.h | 1 + kernel/kernel/Memory/FileBackedRegion.cpp | 2 +- kernel/kernel/Memory/MemoryBackedRegion.cpp | 2 +- kernel/kernel/Memory/MemoryRegion.cpp | 8 ++++++++ kernel/kernel/Process.cpp | 12 +++++++++++- libc/include/sys/banan-os.h | 1 + userspace/meminfo/main.cpp | 1 + 12 files changed, 39 insertions(+), 7 deletions(-) diff --git a/LibELF/LibELF/LoadableELF.cpp b/LibELF/LibELF/LoadableELF.cpp index 9af8c1fa..7a580b3a 100644 --- a/LibELF/LibELF/LoadableELF.cpp +++ b/LibELF/LibELF/LoadableELF.cpp @@ -201,6 +201,7 @@ namespace LibELF return BAN::Error::from_errno(ENOMEM); m_page_table.map_page_at(paddr, vaddr, flags); + m_physical_page_count++; memset((void*)vaddr, 0x00, PAGE_SIZE); @@ -280,6 +281,7 @@ namespace LibELF m_page_table.unmap_page(0); new_page_table.map_page_at(paddr, start + i * PAGE_SIZE, flags); + elf->m_physical_page_count++; } break; diff --git a/LibELF/include/LibELF/LoadableELF.h b/LibELF/include/LibELF/LoadableELF.h index ed8dc416..1b3cc4ff 100644 --- a/LibELF/include/LibELF/LoadableELF.h +++ b/LibELF/include/LibELF/LoadableELF.h @@ -34,6 +34,7 @@ namespace LibELF BAN::ErrorOr> clone(Kernel::PageTable&); size_t virtual_page_count() const { return m_virtual_page_count; } + size_t physical_page_count() const { return m_physical_page_count; } private: LoadableELF(Kernel::PageTable&, BAN::RefPtr); @@ -45,6 +46,7 @@ namespace LibELF ElfNativeFileHeader m_file_header; BAN::Vector m_program_headers; size_t m_virtual_page_count = 0; + size_t m_physical_page_count = 0; }; } \ No newline at end of file diff --git a/kernel/include/kernel/Memory/FileBackedRegion.h b/kernel/include/kernel/Memory/FileBackedRegion.h index b7decd8d..a6160eaa 100644 --- a/kernel/include/kernel/Memory/FileBackedRegion.h +++ b/kernel/include/kernel/Memory/FileBackedRegion.h @@ -26,10 +26,11 @@ namespace Kernel static BAN::ErrorOr> create(BAN::RefPtr, PageTable&, off_t offset, size_t size, AddressRange address_range, Type, PageTable::flags_t); ~FileBackedRegion(); - virtual BAN::ErrorOr allocate_page_containing(vaddr_t vaddr) override; - virtual BAN::ErrorOr> clone(PageTable& new_page_table) override; + protected: + virtual BAN::ErrorOr allocate_page_containing_impl(vaddr_t vaddr) override; + private: FileBackedRegion(BAN::RefPtr, PageTable&, off_t offset, ssize_t size, Type flags, PageTable::flags_t page_flags); diff --git a/kernel/include/kernel/Memory/MemoryBackedRegion.h b/kernel/include/kernel/Memory/MemoryBackedRegion.h index 0b81d1b7..0b778f0c 100644 --- a/kernel/include/kernel/Memory/MemoryBackedRegion.h +++ b/kernel/include/kernel/Memory/MemoryBackedRegion.h @@ -14,7 +14,6 @@ namespace Kernel static BAN::ErrorOr> create(PageTable&, size_t size, AddressRange, Type, PageTable::flags_t); ~MemoryBackedRegion(); - virtual BAN::ErrorOr allocate_page_containing(vaddr_t vaddr) override; virtual BAN::ErrorOr> clone(PageTable& new_page_table) override; @@ -22,6 +21,9 @@ namespace Kernel // This can fail if no memory is mapped and no free memory was available BAN::ErrorOr copy_data_to_region(size_t offset_into_region, const uint8_t* buffer, size_t buffer_size); + protected: + virtual BAN::ErrorOr allocate_page_containing_impl(vaddr_t vaddr) override; + private: MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t); }; diff --git a/kernel/include/kernel/Memory/MemoryRegion.h b/kernel/include/kernel/Memory/MemoryRegion.h index 6d1a7b0d..99a3078d 100644 --- a/kernel/include/kernel/Memory/MemoryRegion.h +++ b/kernel/include/kernel/Memory/MemoryRegion.h @@ -38,11 +38,12 @@ namespace Kernel vaddr_t vaddr() const { return m_vaddr; } size_t virtual_page_count() const { return BAN::Math::div_round_up(m_size, PAGE_SIZE); } + size_t physical_page_count() const { return m_physical_page_count; } // Returns error if no memory was available // Returns true if page was succesfully allocated // Returns false if page was already allocated - virtual BAN::ErrorOr allocate_page_containing(vaddr_t address) = 0; + BAN::ErrorOr allocate_page_containing(vaddr_t address); virtual BAN::ErrorOr> clone(PageTable& new_page_table) = 0; @@ -50,12 +51,15 @@ namespace Kernel MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags); BAN::ErrorOr initialize(AddressRange); + virtual BAN::ErrorOr allocate_page_containing_impl(vaddr_t address) = 0; + protected: PageTable& m_page_table; const size_t m_size; const Type m_type; const PageTable::flags_t m_flags; vaddr_t m_vaddr { 0 }; + size_t m_physical_page_count { 0 }; }; } \ No newline at end of file diff --git a/kernel/include/kernel/Thread.h b/kernel/include/kernel/Thread.h index bb826821..c988f7af 100644 --- a/kernel/include/kernel/Thread.h +++ b/kernel/include/kernel/Thread.h @@ -84,6 +84,7 @@ namespace Kernel bool is_userspace() const { return m_is_userspace; } size_t virtual_page_count() const { return m_stack->size() / PAGE_SIZE; } + size_t physical_page_count() const { return virtual_page_count(); } #if __enable_sse void save_sse() { asm volatile("fxsave %0" :: "m"(m_sse_storage)); } diff --git a/kernel/kernel/Memory/FileBackedRegion.cpp b/kernel/kernel/Memory/FileBackedRegion.cpp index 086c9d62..b4314f6f 100644 --- a/kernel/kernel/Memory/FileBackedRegion.cpp +++ b/kernel/kernel/Memory/FileBackedRegion.cpp @@ -85,7 +85,7 @@ namespace Kernel } } - BAN::ErrorOr FileBackedRegion::allocate_page_containing(vaddr_t address) + BAN::ErrorOr FileBackedRegion::allocate_page_containing_impl(vaddr_t address) { ASSERT(contains(address)); diff --git a/kernel/kernel/Memory/MemoryBackedRegion.cpp b/kernel/kernel/Memory/MemoryBackedRegion.cpp index 971a8592..6554d7c5 100644 --- a/kernel/kernel/Memory/MemoryBackedRegion.cpp +++ b/kernel/kernel/Memory/MemoryBackedRegion.cpp @@ -38,7 +38,7 @@ namespace Kernel } } - BAN::ErrorOr MemoryBackedRegion::allocate_page_containing(vaddr_t address) + BAN::ErrorOr MemoryBackedRegion::allocate_page_containing_impl(vaddr_t address) { ASSERT(m_type == Type::PRIVATE); diff --git a/kernel/kernel/Memory/MemoryRegion.cpp b/kernel/kernel/Memory/MemoryRegion.cpp index e6cd61d0..2e2dab42 100644 --- a/kernel/kernel/Memory/MemoryRegion.cpp +++ b/kernel/kernel/Memory/MemoryRegion.cpp @@ -47,4 +47,12 @@ namespace Kernel return true; } + BAN::ErrorOr MemoryRegion::allocate_page_containing(vaddr_t address) + { + auto ret = allocate_page_containing_impl(address); + if (!ret.is_error() && ret.value()) + m_physical_page_count++; + return ret; + } + } diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 7e237b9a..cca2ee7f 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -257,14 +257,24 @@ namespace Kernel LockGuard _(m_lock); out->page_size = PAGE_SIZE; - out->virt_pages = 0; + out->phys_pages = 0; + for (auto* thread : m_threads) + { out->virt_pages += thread->virtual_page_count(); + out->phys_pages += thread->physical_page_count(); + } for (auto& region : m_mapped_regions) + { out->virt_pages += region->virtual_page_count(); + out->phys_pages += region->physical_page_count(); + } if (m_loadable_elf) + { out->virt_pages += m_loadable_elf->virtual_page_count(); + out->phys_pages += m_loadable_elf->physical_page_count(); + } } BAN::ErrorOr Process::sys_exit(int status) diff --git a/libc/include/sys/banan-os.h b/libc/include/sys/banan-os.h index f514f829..7e4558cf 100644 --- a/libc/include/sys/banan-os.h +++ b/libc/include/sys/banan-os.h @@ -21,6 +21,7 @@ struct proc_meminfo_t { size_t page_size; size_t virt_pages; + size_t phys_pages; }; /* diff --git a/userspace/meminfo/main.cpp b/userspace/meminfo/main.cpp index b9fbbefe..b87118a7 100644 --- a/userspace/meminfo/main.cpp +++ b/userspace/meminfo/main.cpp @@ -48,6 +48,7 @@ int main() printf("process:\n"); printf(" pid: %s\n", proc_ent->d_name); printf(" vmem: %zu pages (%zu bytes)\n", meminfo.virt_pages, meminfo.page_size * meminfo.virt_pages); + printf(" pmem: %zu pages (%zu bytes)\n", meminfo.phys_pages, meminfo.page_size * meminfo.phys_pages); } close(fd);