Linux Kernel Architecture

(Jacob Rumans) #1

Chapter3:MemoryManagement


{
struct page *page;

page = __rmqueue_smallest(zone, order, migratetype);

if (unlikely(!page))
page = __rmqueue_fallback(zone, order, migratetype);

return page;
}

By reference to the desired allocation order, the zone from which the pages are to be removed, and
the migrate type,__rmqueue_smallesscans the page lists until it finds a suitable contiguous chunk of
memory. When it does this, buddies can be split as described in Chapter 1. Should the desired migrate
list not be able to satisfy the request, then other migrate lists are tried as an emergency measure in
__rmqueue_fallback.


The implementation of__rmqueue_smallestis not very long. Essentially, it consists of a loop that iterates
over the list of migrate-type-specific free pages list of the zone in ascending order until an appropriate
entry is found.


mm/page_alloc.c
static struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
int migratetype)
{
unsigned int current_order;
struct free_area * area;
struct page *page;

/* Find a page of the appropriate size in the preferred list */
for (current_order = order; current_order < MAX_ORDER; ++current_order) {
area = &(zone->free_area[current_order]);
if (list_empty(&area->free_list[migratetype]))
continue;

page = list_entry(area->free_list[migratetype].next,
struct page, lru);
list_del(&page->lru);
rmv_page_order(page);
area->nr_free--;
__mod_zone_page_state(zone, NR_FREE_PAGES, - (1UL << order));
expand(zone, page, order, current_order, area, migratetype);
return page;
}

return NULL;
}

The search begins at the entry for the desired allocation order. Smaller areas are of no use because the
pages allocated must be contiguous. Recall that all pages of a given allocation order are again subdivided
into migrate-type-specific lists, and the proper one is selected.

Free download pdf