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.
The page_tree struct was doing a lot of bit manipulation to keep its
base, level, and flags in a single uint64_t. But since this is such a
large structure anyway, another word doesn't change it much and greatly
simplifies both the code and reasoning about it.
I'm a tabs guy. I like tabs, it's an elegant way to represent
indentation instead of brute-forcing it. But I have to admit that the
world seems to be going towards spaces, and tooling tends not to play
nice with tabs. So here we go, changing the whole repo to spaces since
I'm getting tired of all the inconsistent formatting.
The previous method of VMA page tracking relied on the VMA always being
mapped at least into one space and just kept track of pages in the
spaces' page tables. This had a number of drawbacks, and the mapper
system was too complex without much benefit.
Now make VMAs themselves keep track of spaces that they're a part of,
and make them responsible for knowing what page goes where. This
simplifies most types of VMA greatly. The new vm_area_open (nee
vm_area_shared, but there is now no reason for most VMAs to be
explicitly shareable) adds a 64-ary radix tree for tracking allocated
pages.
The page_tree cannot yet handle taking pages away, but this isn't
something jsix can do yet anyway.