[Zion] Actually free memory pages when a MemoryObject goes out of scope
This commit is contained in:
parent
344e84c313
commit
4d1846a7d5
|
@ -55,9 +55,6 @@ glcr::ErrorCode MemoryMappingTree::FreeMemoryRange(uint64_t vaddr_base,
|
||||||
|
|
||||||
auto find_or = mapping_tree_.Find(vaddr_base);
|
auto find_or = mapping_tree_.Find(vaddr_base);
|
||||||
if (find_or) {
|
if (find_or) {
|
||||||
dbgln("Mem addr {x} refcnt {}",
|
|
||||||
(uint64_t)find_or.value().get().mem_object.get(),
|
|
||||||
find_or.value().get().mem_object->ref_count());
|
|
||||||
mapping_tree_.Delete(vaddr_base);
|
mapping_tree_.Delete(vaddr_base);
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
@ -130,8 +130,8 @@ void WriteInitProgram(glcr::RefPtr<Port> port, glcr::String name, uint64_t id) {
|
||||||
|
|
||||||
glcr::ErrorCode WritePciVmmo(glcr::RefPtr<Port> port, uint64_t id) {
|
glcr::ErrorCode WritePciVmmo(glcr::RefPtr<Port> port, uint64_t id) {
|
||||||
ASSIGN_OR_RETURN(PcieConfiguration config, GetPciExtendedConfiguration());
|
ASSIGN_OR_RETURN(PcieConfiguration config, GetPciExtendedConfiguration());
|
||||||
auto vmmo =
|
auto vmmo = glcr::MakeRefCounted<FixedMemoryObject>(config.base,
|
||||||
glcr::MakeRefCounted<FixedMemoryObject>(config.base, config.offset);
|
config.offset, false);
|
||||||
|
|
||||||
port->WriteKernel(id, MakeRefCounted<Capability>(vmmo));
|
port->WriteKernel(id, MakeRefCounted<Capability>(vmmo));
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "boot/boot_info.h"
|
#include "boot/boot_info.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
|
#include "memory/constants.h"
|
||||||
|
|
||||||
#define K_PHYS_DEBUG 0
|
#define K_PHYS_DEBUG 0
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ class PhysicalMemoryManager {
|
||||||
#endif
|
#endif
|
||||||
size -= bootstrap_used;
|
size -= bootstrap_used;
|
||||||
}
|
}
|
||||||
AddMemoryRegion(base, size);
|
AddMemoryRegion(base, size / kPageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +66,7 @@ class PhysicalMemoryManager {
|
||||||
|
|
||||||
MemBlock& block = memory_blocks.PeekFront();
|
MemBlock& block = memory_blocks.PeekFront();
|
||||||
uint64_t page = block.base;
|
uint64_t page = block.base;
|
||||||
block.base += 0x1000;
|
block.base += kPageSize;
|
||||||
block.num_pages--;
|
block.num_pages--;
|
||||||
if (block.num_pages == 0) {
|
if (block.num_pages == 0) {
|
||||||
memory_blocks.PopFront();
|
memory_blocks.PopFront();
|
||||||
|
@ -97,7 +98,7 @@ class PhysicalMemoryManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t page = iter->base;
|
uint64_t page = iter->base;
|
||||||
iter->base += num_pages * 0x1000;
|
iter->base += num_pages * kPageSize;
|
||||||
iter->num_pages -= num_pages;
|
iter->num_pages -= num_pages;
|
||||||
#if K_PHYS_DEBUG
|
#if K_PHYS_DEBUG
|
||||||
dbgln("Continuous {x}:{}", page, num_pages);
|
dbgln("Continuous {x}:{}", page, num_pages);
|
||||||
|
@ -105,11 +106,17 @@ class PhysicalMemoryManager {
|
||||||
allocated_pages_ += num_pages;
|
allocated_pages_ += num_pages;
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreePage(uint64_t page) {
|
void FreePage(uint64_t page) {
|
||||||
AddMemoryRegion(page, 0x1000);
|
AddMemoryRegion(page, 1);
|
||||||
allocated_pages_--;
|
allocated_pages_--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FreePages(uint64_t page, uint64_t num_pages) {
|
||||||
|
AddMemoryRegion(page, num_pages);
|
||||||
|
allocated_pages_ -= num_pages;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t AllocatedPages() { return allocated_pages_; }
|
uint64_t AllocatedPages() { return allocated_pages_; }
|
||||||
|
|
||||||
uint64_t AvailablePages() {
|
uint64_t AvailablePages() {
|
||||||
|
@ -130,10 +137,10 @@ class PhysicalMemoryManager {
|
||||||
|
|
||||||
uint64_t allocated_pages_ = 0;
|
uint64_t allocated_pages_ = 0;
|
||||||
|
|
||||||
void AddMemoryRegion(uint64_t base, uint64_t size) {
|
void AddMemoryRegion(uint64_t base, uint64_t num_pages) {
|
||||||
MemBlock block{
|
MemBlock block{
|
||||||
.base = base,
|
.base = base,
|
||||||
.num_pages = size >> 12,
|
.num_pages = num_pages,
|
||||||
};
|
};
|
||||||
memory_blocks.PushFront(block);
|
memory_blocks.PushFront(block);
|
||||||
}
|
}
|
||||||
|
@ -232,8 +239,22 @@ uint64_t AllocateContinuous(uint64_t num_continuous) {
|
||||||
return gPmm->AllocateContinuous(num_continuous);
|
return gPmm->AllocateContinuous(num_continuous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FreePage(uint64_t page) {
|
||||||
|
if (gPmm == nullptr) {
|
||||||
|
panic("No physical memory manager!");
|
||||||
|
}
|
||||||
|
gPmm->FreePage(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreePages(uint64_t page, uint64_t num_pages) {
|
||||||
|
if (gPmm == nullptr) {
|
||||||
|
panic("No physical memory manager!");
|
||||||
|
}
|
||||||
|
gPmm->FreePages(page, num_pages);
|
||||||
|
}
|
||||||
|
|
||||||
void DumpPhysicalMemoryUsage() {
|
void DumpPhysicalMemoryUsage() {
|
||||||
dbgln("Pages used: {} MiB, avail: {} MiB", gPmm->AllocatedPages() / 256,
|
dbgln("Pages used: {} KiB, avail: {} MiB", gPmm->AllocatedPages() * 4,
|
||||||
gPmm->AvailablePages() / 256);
|
gPmm->AvailablePages() / 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,9 @@ uint64_t AllocatePage();
|
||||||
uint64_t AllocateAndZeroPage();
|
uint64_t AllocateAndZeroPage();
|
||||||
|
|
||||||
uint64_t AllocateContinuous(uint64_t num_pages);
|
uint64_t AllocateContinuous(uint64_t num_pages);
|
||||||
|
|
||||||
void FreePage(uint64_t page);
|
void FreePage(uint64_t page);
|
||||||
|
void FreePages(uint64_t page, uint64_t num_pages);
|
||||||
|
|
||||||
void DumpPhysicalMemoryUsage();
|
void DumpPhysicalMemoryUsage();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ glcr::RefPtr<AddressSpace> AddressSpace::ForRoot() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressSpace::AddressSpace() {
|
AddressSpace::AddressSpace() {
|
||||||
cr3_ = phys_mem::AllocatePage();
|
cr3_ = phys_mem::AllocateAndZeroPage();
|
||||||
InitializePml4(cr3_);
|
InitializePml4(cr3_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,13 @@ MemoryObject::MemoryObject(uint64_t size) : size_(size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryObject::~MemoryObject() { dbgln("Memory Object Freed"); }
|
MemoryObject::~MemoryObject() {
|
||||||
|
for (uint64_t page : phys_page_list_) {
|
||||||
|
if (page != 0) {
|
||||||
|
phys_mem::FreePage(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t MemoryObject::PhysicalPageAtOffset(uint64_t offset) {
|
uint64_t MemoryObject::PhysicalPageAtOffset(uint64_t offset) {
|
||||||
if (offset > size_) {
|
if (offset > size_) {
|
||||||
|
@ -70,6 +76,12 @@ uint64_t MemoryObject::PageNumberToPhysAddr(uint64_t page_num) {
|
||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FixedMemoryObject::~FixedMemoryObject() {
|
||||||
|
if (should_free_) {
|
||||||
|
phys_mem::FreePages(physical_addr_, num_pages());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glcr::ErrorOr<glcr::RefPtr<MemoryObject>> FixedMemoryObject::Duplicate(
|
glcr::ErrorOr<glcr::RefPtr<MemoryObject>> FixedMemoryObject::Duplicate(
|
||||||
uint64_t offset, uint64_t length) {
|
uint64_t offset, uint64_t length) {
|
||||||
if (offset + length > size()) {
|
if (offset + length > size()) {
|
||||||
|
@ -77,5 +89,6 @@ glcr::ErrorOr<glcr::RefPtr<MemoryObject>> FixedMemoryObject::Duplicate(
|
||||||
}
|
}
|
||||||
|
|
||||||
return glcr::StaticCastRefPtr<MemoryObject>(
|
return glcr::StaticCastRefPtr<MemoryObject>(
|
||||||
glcr::MakeRefCounted<FixedMemoryObject>(physical_addr_ + offset, length));
|
glcr::MakeRefCounted<FixedMemoryObject>(physical_addr_ + offset, length,
|
||||||
|
false));
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ class MemoryObject : public KernelObject {
|
||||||
~MemoryObject();
|
~MemoryObject();
|
||||||
|
|
||||||
uint64_t size() { return size_; }
|
uint64_t size() { return size_; }
|
||||||
uint64_t num_pages() { return size_ / 0x1000; }
|
uint64_t num_pages() { return ((size_ - 1) / 0x1000) + 1; }
|
||||||
|
|
||||||
uint64_t PhysicalPageAtOffset(uint64_t offset);
|
uint64_t PhysicalPageAtOffset(uint64_t offset);
|
||||||
|
|
||||||
|
@ -58,14 +58,20 @@ class MemoryObject : public KernelObject {
|
||||||
class FixedMemoryObject : public MemoryObject {
|
class FixedMemoryObject : public MemoryObject {
|
||||||
public:
|
public:
|
||||||
// FIXME: Validate that this is 4k aligned.
|
// FIXME: Validate that this is 4k aligned.
|
||||||
FixedMemoryObject(uint64_t physical_addr, uint64_t size)
|
// Create a new class object for should free.
|
||||||
: MemoryObject(size, true), physical_addr_(physical_addr) {}
|
FixedMemoryObject(uint64_t physical_addr, uint64_t size, bool should_free)
|
||||||
|
: MemoryObject(size, true),
|
||||||
|
physical_addr_(physical_addr),
|
||||||
|
should_free_(should_free) {}
|
||||||
|
|
||||||
|
~FixedMemoryObject();
|
||||||
|
|
||||||
virtual glcr::ErrorOr<glcr::RefPtr<MemoryObject>> Duplicate(
|
virtual glcr::ErrorOr<glcr::RefPtr<MemoryObject>> Duplicate(
|
||||||
uint64_t offset, uint64_t length) override;
|
uint64_t offset, uint64_t length) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t physical_addr_;
|
uint64_t physical_addr_;
|
||||||
|
bool should_free_;
|
||||||
|
|
||||||
uint64_t PageNumberToPhysAddr(uint64_t page_num) override {
|
uint64_t PageNumberToPhysAddr(uint64_t page_num) override {
|
||||||
return physical_addr_ + (0x1000 * page_num);
|
return physical_addr_ + (0x1000 * page_num);
|
||||||
|
|
|
@ -14,7 +14,8 @@ z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req) {
|
||||||
z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) {
|
z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) {
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
uint64_t paddr = req->paddr;
|
uint64_t paddr = req->paddr;
|
||||||
auto vmmo_ref = glcr::MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
auto vmmo_ref =
|
||||||
|
glcr::MakeRefCounted<FixedMemoryObject>(paddr, req->size, false);
|
||||||
*req->vmmo_cap =
|
*req->vmmo_cap =
|
||||||
curr_proc.AddNewCapability(StaticCastRefPtr<MemoryObject>(vmmo_ref));
|
curr_proc.AddNewCapability(StaticCastRefPtr<MemoryObject>(vmmo_ref));
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
|
@ -22,8 +23,10 @@ z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) {
|
||||||
|
|
||||||
z_err_t MemoryObjectCreateContiguous(ZMemoryObjectCreateContiguousReq* req) {
|
z_err_t MemoryObjectCreateContiguous(ZMemoryObjectCreateContiguousReq* req) {
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
uint64_t paddr = phys_mem::AllocateContinuous(((req->size - 1) / 0x1000) + 1);
|
uint64_t num_pages = ((req->size - 1) / 0x1000) + 1;
|
||||||
auto vmmo_ref = glcr::MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
uint64_t paddr = phys_mem::AllocateContinuous(num_pages);
|
||||||
|
auto vmmo_ref =
|
||||||
|
glcr::MakeRefCounted<FixedMemoryObject>(paddr, req->size, true);
|
||||||
*req->vmmo_cap =
|
*req->vmmo_cap =
|
||||||
curr_proc.AddNewCapability(StaticCastRefPtr<MemoryObject>(vmmo_ref));
|
curr_proc.AddNewCapability(StaticCastRefPtr<MemoryObject>(vmmo_ref));
|
||||||
*req->paddr = paddr;
|
*req->paddr = paddr;
|
||||||
|
|
Loading…
Reference in New Issue