mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[kernel] Improve VMA lifecycle
The vm_area objects had a number of issues I have been running into when working on srv.init: - It was impossible to map a VMA, fill it, unmap it, and hand it to another process. Unmapping the VMA in this process would cause all the pages to be freed, since it was removed from its last mapping. - If a VMA was marked with vm_flag::zero, it would be zeroed out _every time_ it was mapped into a vm_space. - The vm_area_open class was leaking its page_tree nodes. In order to fix these issues, the different VMA types all work slightly differently now: - Physical pages allocated for a VMA are now freed when the VMA is deleted, not when it is unmapped. - A knock-on effect from the first point is that vm_area_guarded is now based on vm_area_open, instead of vm_area_untracked. An untracked area cannot free its pages, since it does not track them. - The vm_area_open type now deletes its root page_tree node. And page_tree nodes will delete child nodes or free physical pages in their dtors. - vm_flag::zero has been removed; pages will need to be zeroed out further at a higher level. - vm_area also no longer deletes itself only on losing its last handle - it will only self-delete when all handles _and_ mappings are gone.
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
#include "kernel_memory.h"
|
||||
#include "page_tree.h"
|
||||
|
||||
// Page tree levels map the following parts of a pagewise offset. Note the xxx
|
||||
// are not part of the offset but represent the bits added for the actual virtual
|
||||
// address. (Also note that level 0's entries are physical page addrs, the rest
|
||||
// map other page_tree nodes)
|
||||
// Page tree levels map the following parts of an offset. Note the xxx part of
|
||||
// the offset but represent the bits of the actual sub-page virtual address.
|
||||
// (Also note that level 0's entries are physical page addrs, the rest map
|
||||
// other page_tree nodes)
|
||||
//
|
||||
// Level 0: 0000 0000 0003 fxxx 64 pages / 256 KiB
|
||||
// Level 1: 0000 0000 00fc 0xxx 4K pages / 16 MiB -- 24-bit addressing
|
||||
@@ -36,6 +36,20 @@ page_tree::page_tree(uint64_t base, uint8_t level) :
|
||||
kutil::memset(m_entries, 0, sizeof(m_entries));
|
||||
}
|
||||
|
||||
page_tree::~page_tree()
|
||||
{
|
||||
if (m_level) {
|
||||
for (auto &e : m_entries)
|
||||
delete e.child;
|
||||
} else {
|
||||
auto &fa = frame_allocator::get();
|
||||
for (auto &e : m_entries) {
|
||||
if (e.entry & 1)
|
||||
fa.free(e.entry & ~0xfffull, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
page_tree::contains(uint64_t offset, uint8_t &index) const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user