Implementing a stack-based page frame allocator
Posted: Mon Mar 29, 2021 4:26 pm
I have recently been trying to write a page frame allocator, using information from sources such as Page Frame Allocation on the wiki. Looking at the common algorithms, it seemed that keeping the list of free pages in a stack is the simplest one that has good time complexity (constant time per allocation and free).
According to a forum post (I don't remember which), the way this is usually done is: for every free physical page, a pointer is stored in the page (say, at the beginning) providing the physical address of the page immediately below it on the stack. As long as the kernel keeps track of where the top of the stack is, pages can be pushed to or popped from the stack.
The problem I now face is when paging is enabled and one can no longer access memory simply with a physical address, which means that we cannot read the "next page" pointer (because we know only the physical address of the top of the stack), or write a pointer into a newly freed page (as only the physical address of the page being freed is available).
Disabling paging is obviously not a reasonable solution. Another possibility that I have considered is: whenever one needs to read/write a physical address in this process, temporarily map the address to a dedicated location in the address space (using the recursive mapping trick to modify the paging structures), and perform the needed operation from there. However, this does not seem to be a commonly used approach, and I have concerns about its efficiency, since one has to map the page into the address space before modifying it.
What is the proper way to deal with this situation? Or should I store the allocator's stack in some other way?
According to a forum post (I don't remember which), the way this is usually done is: for every free physical page, a pointer is stored in the page (say, at the beginning) providing the physical address of the page immediately below it on the stack. As long as the kernel keeps track of where the top of the stack is, pages can be pushed to or popped from the stack.
The problem I now face is when paging is enabled and one can no longer access memory simply with a physical address, which means that we cannot read the "next page" pointer (because we know only the physical address of the top of the stack), or write a pointer into a newly freed page (as only the physical address of the page being freed is available).
Disabling paging is obviously not a reasonable solution. Another possibility that I have considered is: whenever one needs to read/write a physical address in this process, temporarily map the address to a dedicated location in the address space (using the recursive mapping trick to modify the paging structures), and perform the needed operation from there. However, this does not seem to be a commonly used approach, and I have concerns about its efficiency, since one has to map the page into the address space before modifying it.
What is the proper way to deal with this situation? Or should I store the allocator's stack in some other way?