Chapter3:MemoryManagement
The relationship betweenfree_pagesand__free_pagesis established by means of a function instead of
a macro because the virtual address must first be converted to a pointer tostruct page.
mm/page_alloc.c
void free_pages(unsigned long addr, unsigned int order)
{
if (addr != 0) {
__free_pages(virt_to_page(addr), order);
}
}
virt_to_pageconverts virtual memory addresses to pointers topageinstances. Basically, this is the
reverse of thepage_addresshelper function introduced above.
Figure 3-31 summarizes the relationships among the various memory-freeing functions in a graphical
overview.
free_page
free_pages
__free_pages
__free_page
Figure 3-31: Relationships
among the memory-freeing
functions of the buddy
system.
3.5.5 Reserving Pages
All API functions lead back toalloc_pages_node, which is a kind of ‘‘launch pad‘‘ for central implemen-
tation of the buddy system.
<gfp.h>
static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
unsigned int order)
{
if (unlikely(order >= MAX_ORDER))
return NULL;
/* Unknown node is current node */
if (nid < 0)
nid = numa_node_id();
return __alloc_pages(gfp_mask, order,
NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_mask));
}
Just a simple check is carried out to ensure that no overly large memory chunk is allocated. If a neg-
ative node ID (which does not exist) is specified, the kernel automatically uses the ID that belongs to