Linux Kernel Architecture

(Jacob Rumans) #1

Chapter3:MemoryManagement


...
if (PageBuddy(buddy) && page_order(buddy) == order) {
return 1;
}
return 0;
}

If the first page of the buddy group is in the buddy system, then thePG_buddybit of the corresponding
struct pageinstance is set. This, however, is not sufficient to reunite two buddies: When freeing a page
group with 2orderpages, the kernel must ensure that 2orderpages of the second buddy are contained
in the buddy system. This is easy to check because the page order of the free group is stored in the first
privateelement of thestruct pageinstance of a free group, andpage_orderreads this value. Note that
page_is_buddyis slightly more complicated in reality because it needs to account for memory holes, but
this is omitted to simplify matters.

Table 3-8: Calculations When a Page is Placed Back into the Buddy System.

order page_idx buddy_index - page_index __find_combined_index

010 1 10


110 - 2 8


28 4 8


38 - 8 0


The following code determines whether a buddy pair can be coalesced:

mm/page_alloc.c
static inline void __free_one_page(struct page *page,
struct zone *zone, unsigned int order)
{
int migratetype = get_pageblock_migratetype(page);
...
while (order < MAX_ORDER-1) {
unsigned long combined_idx;
struct page *buddy;

buddy = __page_find_buddy(page, page_idx, order);
if (!page_is_buddy(page, buddy, order))
break; /* Move the buddy up one level. */

list_del(&buddy->lru);
zone->free_area[order].nr_free--;
rmv_page_order(buddy);
combined_idx = __find_combined_index(page_idx, order);
page = page + (combined_idx - page_idx);
page_idx = combined_idx;
order++;
}
...
Free download pdf