We'll talk about page_alloc, page_free, alloc_kpages and free_kpages.

Allocate one single physical page with page_alloc

This is relatively easy once you've decided which paging algorithm to use. FIFO seems good enough in in terms of simplicity as well as acceptable performance. We just scan the coremap, find out if there is any FREE page, or find out the oldest page. At this stage (before swapping), I will use a magic function called MAKE_PAGE_AVAIL, which obviously makes a page available, by flushing or swapping, we don't care :-). Once we find a victim (maybe free, clean, or dirty, but must not be fixed), we call MAKE_PAGE_AVAIL on it, and update it's internal fields like time stamp, as, va, etc. And don't forget to zero the page before we return.

A trade-off here is what parameters should we pass to page_alloc? One choice is nothing: I just tell you to give me a page, and I'll deal with the page meta-info by myself. But this manner will probably cause page-info inconsistency, e.g., caller forget to set page's state. So to avoid this case, I prefer caller tell page_alloc all he needs, like as, va, whether the allocate page need to keep in memory, etc. And let page_alloc set the page's meta info accordingly.

BTW, since coremap is a globally share data structure, so you really want to use lock to protect it every time you read/write it.

Allocate n continuous pages with page_nalloc

Since kernel address will bypass TLB and are directly-mapped. (See this and this for details), when we're asked to allocate n (where n > 1) pages by alloc_kpages, we must allocate n continuous pages! To do this, we need to first find a chunk of n available (i.e., not fixed) continuous pages, and then call MAKE_PAGE_AVAILABLE on these pages. Like page_alloc, we also need to update the coremap and zero the allocated memory.

As mentioned in my previous blog about coremap, in alloc_kpages, we need to first check whether vm has bootstrapped: if not, we just use get_ppages, otherwise, we use our powerful page_nalloc.

Also, we need to record how many pages we allocated so that when calling free_kpages, we can free all these npagespage.

Free a page with page_free and free_kpages

We just need to mark this page as FREE. But if this page was mapped to user address space (page->as != NULL), then we need first unmap it, and shoot down the TLB entry if needed. We'll talk about user address space management lately.

Only one tip for this part, do not forget to protect every access to coremap using lock (but not spinlock).