Kernel: Add physical memory info to /proc/{pid}/meminfo

This commit is contained in:
Bananymous 2023-09-30 22:11:45 +03:00
parent 762b7a4276
commit 797ca65c66
12 changed files with 39 additions and 7 deletions

View File

@ -201,6 +201,7 @@ namespace LibELF
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
m_page_table.map_page_at(paddr, vaddr, flags); m_page_table.map_page_at(paddr, vaddr, flags);
m_physical_page_count++;
memset((void*)vaddr, 0x00, PAGE_SIZE); memset((void*)vaddr, 0x00, PAGE_SIZE);
@ -280,6 +281,7 @@ namespace LibELF
m_page_table.unmap_page(0); m_page_table.unmap_page(0);
new_page_table.map_page_at(paddr, start + i * PAGE_SIZE, flags); new_page_table.map_page_at(paddr, start + i * PAGE_SIZE, flags);
elf->m_physical_page_count++;
} }
break; break;

View File

@ -34,6 +34,7 @@ namespace LibELF
BAN::ErrorOr<BAN::UniqPtr<LoadableELF>> clone(Kernel::PageTable&); BAN::ErrorOr<BAN::UniqPtr<LoadableELF>> clone(Kernel::PageTable&);
size_t virtual_page_count() const { return m_virtual_page_count; } size_t virtual_page_count() const { return m_virtual_page_count; }
size_t physical_page_count() const { return m_physical_page_count; }
private: private:
LoadableELF(Kernel::PageTable&, BAN::RefPtr<Kernel::Inode>); LoadableELF(Kernel::PageTable&, BAN::RefPtr<Kernel::Inode>);
@ -45,6 +46,7 @@ namespace LibELF
ElfNativeFileHeader m_file_header; ElfNativeFileHeader m_file_header;
BAN::Vector<ElfNativeProgramHeader> m_program_headers; BAN::Vector<ElfNativeProgramHeader> m_program_headers;
size_t m_virtual_page_count = 0; size_t m_virtual_page_count = 0;
size_t m_physical_page_count = 0;
}; };
} }

View File

@ -26,10 +26,11 @@ namespace Kernel
static BAN::ErrorOr<BAN::UniqPtr<FileBackedRegion>> create(BAN::RefPtr<Inode>, PageTable&, off_t offset, size_t size, AddressRange address_range, Type, PageTable::flags_t); static BAN::ErrorOr<BAN::UniqPtr<FileBackedRegion>> create(BAN::RefPtr<Inode>, PageTable&, off_t offset, size_t size, AddressRange address_range, Type, PageTable::flags_t);
~FileBackedRegion(); ~FileBackedRegion();
virtual BAN::ErrorOr<bool> allocate_page_containing(vaddr_t vaddr) override;
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override; virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
protected:
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr) override;
private: private:
FileBackedRegion(BAN::RefPtr<Inode>, PageTable&, off_t offset, ssize_t size, Type flags, PageTable::flags_t page_flags); FileBackedRegion(BAN::RefPtr<Inode>, PageTable&, off_t offset, ssize_t size, Type flags, PageTable::flags_t page_flags);

View File

@ -14,7 +14,6 @@ namespace Kernel
static BAN::ErrorOr<BAN::UniqPtr<MemoryBackedRegion>> create(PageTable&, size_t size, AddressRange, Type, PageTable::flags_t); static BAN::ErrorOr<BAN::UniqPtr<MemoryBackedRegion>> create(PageTable&, size_t size, AddressRange, Type, PageTable::flags_t);
~MemoryBackedRegion(); ~MemoryBackedRegion();
virtual BAN::ErrorOr<bool> allocate_page_containing(vaddr_t vaddr) override;
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override; virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> 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 // This can fail if no memory is mapped and no free memory was available
BAN::ErrorOr<void> copy_data_to_region(size_t offset_into_region, const uint8_t* buffer, size_t buffer_size); BAN::ErrorOr<void> copy_data_to_region(size_t offset_into_region, const uint8_t* buffer, size_t buffer_size);
protected:
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr) override;
private: private:
MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t); MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t);
}; };

View File

@ -38,11 +38,12 @@ namespace Kernel
vaddr_t vaddr() const { return m_vaddr; } vaddr_t vaddr() const { return m_vaddr; }
size_t virtual_page_count() const { return BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE); } size_t virtual_page_count() const { return BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE); }
size_t physical_page_count() const { return m_physical_page_count; }
// Returns error if no memory was available // Returns error if no memory was available
// Returns true if page was succesfully allocated // Returns true if page was succesfully allocated
// Returns false if page was already allocated // Returns false if page was already allocated
virtual BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address) = 0; BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address);
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) = 0; virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) = 0;
@ -50,12 +51,15 @@ namespace Kernel
MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags); MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags);
BAN::ErrorOr<void> initialize(AddressRange); BAN::ErrorOr<void> initialize(AddressRange);
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t address) = 0;
protected: protected:
PageTable& m_page_table; PageTable& m_page_table;
const size_t m_size; const size_t m_size;
const Type m_type; const Type m_type;
const PageTable::flags_t m_flags; const PageTable::flags_t m_flags;
vaddr_t m_vaddr { 0 }; vaddr_t m_vaddr { 0 };
size_t m_physical_page_count { 0 };
}; };
} }

View File

@ -84,6 +84,7 @@ namespace Kernel
bool is_userspace() const { return m_is_userspace; } bool is_userspace() const { return m_is_userspace; }
size_t virtual_page_count() const { return m_stack->size() / PAGE_SIZE; } 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 #if __enable_sse
void save_sse() { asm volatile("fxsave %0" :: "m"(m_sse_storage)); } void save_sse() { asm volatile("fxsave %0" :: "m"(m_sse_storage)); }

View File

@ -85,7 +85,7 @@ namespace Kernel
} }
} }
BAN::ErrorOr<bool> FileBackedRegion::allocate_page_containing(vaddr_t address) BAN::ErrorOr<bool> FileBackedRegion::allocate_page_containing_impl(vaddr_t address)
{ {
ASSERT(contains(address)); ASSERT(contains(address));

View File

@ -38,7 +38,7 @@ namespace Kernel
} }
} }
BAN::ErrorOr<bool> MemoryBackedRegion::allocate_page_containing(vaddr_t address) BAN::ErrorOr<bool> MemoryBackedRegion::allocate_page_containing_impl(vaddr_t address)
{ {
ASSERT(m_type == Type::PRIVATE); ASSERT(m_type == Type::PRIVATE);

View File

@ -47,4 +47,12 @@ namespace Kernel
return true; return true;
} }
BAN::ErrorOr<bool> 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;
}
} }

View File

@ -257,14 +257,24 @@ namespace Kernel
LockGuard _(m_lock); LockGuard _(m_lock);
out->page_size = PAGE_SIZE; out->page_size = PAGE_SIZE;
out->virt_pages = 0; out->virt_pages = 0;
out->phys_pages = 0;
for (auto* thread : m_threads) for (auto* thread : m_threads)
{
out->virt_pages += thread->virtual_page_count(); out->virt_pages += thread->virtual_page_count();
out->phys_pages += thread->physical_page_count();
}
for (auto& region : m_mapped_regions) for (auto& region : m_mapped_regions)
{
out->virt_pages += region->virtual_page_count(); out->virt_pages += region->virtual_page_count();
out->phys_pages += region->physical_page_count();
}
if (m_loadable_elf) if (m_loadable_elf)
{
out->virt_pages += m_loadable_elf->virtual_page_count(); out->virt_pages += m_loadable_elf->virtual_page_count();
out->phys_pages += m_loadable_elf->physical_page_count();
}
} }
BAN::ErrorOr<long> Process::sys_exit(int status) BAN::ErrorOr<long> Process::sys_exit(int status)

View File

@ -21,6 +21,7 @@ struct proc_meminfo_t
{ {
size_t page_size; size_t page_size;
size_t virt_pages; size_t virt_pages;
size_t phys_pages;
}; };
/* /*

View File

@ -48,6 +48,7 @@ int main()
printf("process:\n"); printf("process:\n");
printf(" pid: %s\n", proc_ent->d_name); 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(" 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); close(fd);