GMorgan wrote:
Hi Guys,
I've been thinking about how an L4 style microkernel would handle memory management and have a few questions about how certain scenarios would commonly play out.
Just for reference assume something like the Linux structures. In L4 the buddy algorithm lives in a userspace process. When another process wants a page it'll IPC the memory manager and the manager IPCs back with a map instruction the kernel honours built in. The kernel is the sole arbiter of the page tables and provided the sending process has the right to map that page it will honour the request.
When the kernel wants to evict a page it will IPC with the page in question for the memory manager to page it out.
Two scenarios bother me. How does the memory manager give itself more pages? How does the kernel get more pages?
For the first the manager knows nothing about page tables but I assume it can trivially self IPC to map. Is that how this is commonly done?
For the second the kernel obviously cannot just steal a page because it will invalidate the memory managers internal structures which it must know nothing about (if it starts poking the memory managers structures we may as well move it all in kernel).
One option is that the kernel could reserve an area of memory for its own use before it starts the memory manager. In fact, unless the code and data that the kernel needs to start the memory manager is never again used for any other purpose (and can have the memory holding it deallocated), the kernel already has to do this to some degree, and the memory manager will never own *all* the memory on the system.
And in fact, designing the memory manager with the assumption that it does not own all the memory on the system has other advantages: For sandboxing, you could have multiple instances of the memory manager that operate on disjoint subsets of physical memory. For debugging, you could have an instance of the memory manager, instead of operating on physical memory, instead operating on a region in the address space of the debugger. The memory manager just needs to know that it is allocating pages from an address space, not the nature of that address space.
Quote:
Obviously there are special considerations, the memory manager must never OOM the kernel.
Mustn't it? The memory manager just needs to tell the kernel that there is no memory left in the pool it manages to allocate from. The kernel may have pre-allocated, in which case the OOM just tells it that it needs to fall back on its pre-allocated pool and that the size of that pool is all that it has until further notice, so it needs to defer non-critical allocations. There may be separate memory managers running for general allocation without special requirements on location in physical memory and for providing physically contiguous buffers for device drivers, and if the manager for the general pool reports empty, the kernel could start allocating out of the contiguous pool. The allocation may be for some non-critical kernel functionality and the kernel may be able to proceed without the allocation succeeding. The kernel may implement an OOM killer and be able to kill a process to free up memory, in which case an OOM response to a kernel allocation request is the kernel's signal to ready the guillotine.
And if the kernel absolutely needs the memory and there is absolutely nowhere it can get new memory from, then the kernel needs to panic and it might as well know sooner rather than later.
It's the kernel's job to decide on what the policy should be in an OOM situation, the memory manager just needs to honestly inform the kernel when such a situation develops.