Chapter3:MemoryManagement
❑ If__GFP_ZEROis set,prep_zero_pagefills the page with zero bytes using an efficient,
architecture-specific function.
❑ If__GFP_COMPis set and more than one page has been requested, the kernel must group the
pages intocompound pages. The first page is called thehead page, while all other pages are called
tail pages. The structure of compound pages is shown in Figure 3-33.
All pages are identified as compound pages by thePG_compoundbit. Theprivateelements of
thepageinstance ofallpages — even the head page itself — point to the head page. Besides,
the kernel needs to store information on how to free the compound page. This requires both a
function to free the page and information on how many pages compose the compound page.
The LRU list element of the first tail page is abused for this purpose: A pointer to a destructor
function is thus kept inlru.next, while the allocation order is stored inlru.prev.Noticethat
thelruelement cannot be used for this purpose because it is required if the compound page is
to be kept on a kernel list.
Why is this information required? The kernel can combine multiple adjacent physical pages to a
so-called huge-TLB page. When a userland application works with large chunks of data, many
processors allow using huge-TLB pages to keep the data in memory. Since the page size of a
huge-TLB page is larger than the regular page size, this reduces the amount of information that
must be stored in the translation lookaside buffer (TLB), that, in turn, reduces the probability of
a TLB cache miss — and thus speeds things up.^22 However, huge-TLB pages need to be freed
differently than compound pages composed of multiple regular pages, so an explicit destructor
is required.free_compound_pagesis used for this purpose. The function essentially determines
the page order stored inlru.prevand frees the pages one after another when the compound
page is freed.
The auxiliary functionprep_compound_pageis used to arrange the described structure.
PG_compound
private
Iru.next
Iru.prev
PG_compound
private
Iru.next
2 n pages
Iru.prev
PG_compound
private
PG_compound
private
struct
page
free_compound_page
n
Figure 3-33: Higher-order allocations generate compound pages in which the
individual pages are linked.
The__rmqueueHelper Function
The kernel uses the__rmqueuefunction (whose purpose is evidentfrom the preceding description),
which acts as a gatekeeper to penetrate into the innermost core of the buddy system:
mm/page_alloc.c
static struct page *__rmqueue(struct zone *zone, unsigned int order,
int migratetype)
(^22) Huge-TLB pages are created at boot time and kept in a special cache. The kernel parameterhugepagesallows for specifying
how many huge-TLB pages are to be created, and applications can request them via the special filesystem hugetlbfs. The library
libhugetlbfsallows userland applications to use huge-TLB pageswithout direct interference with this filesystem.