Implementation of the partner algorithm-assigning page boxes

Source: Internet
Author: User

The Alloc_pages series page-box allocation functions in the kernel are implemented based on the partner algorithm, which eventually calls the partner algorithm's entry function, Buffered_rmqueue ().

The Linux kernel manages three ways of physical memory, one of which is the classic partner algorithm. However, the basic unit of allocation of physical memory by the partner algorithm is the page box, so the kernel introduces the slab mechanism, and the physical memory allocator based on this mechanism can allocate the physical memory less than the page frame quickly and efficiently, and can effectively avoid the internal fragmentation. In addition, the kernel often requests a single page frame size of physical memory, so the kernel introduces the PER-CPU mechanism, which is designed to quickly allocate a single page box.

1.__rmqueue ()

In fact, the Buffered_rmqueue () function still does not have a true page box assignment, the function first determines whether the allocation order is 0, if it is enabled PER-CPU mechanism to allocate physical memory, otherwise call __rmqueue ().

static struct page *__rmqueue (struct zone *zone, unsigned int order,
int migratetype)
{
struct page *page;
Retry_reserve:
page = __rmqueue_smallest (zone, Order, migratetype);

if (Unlikely (!page) && migratetype! = Migrate_reserve) {
page = __rmqueue_fallback (zone, Order, migratetype);

if (!page) {
Migratetype = Migrate_reserve;
Goto Retry_reserve;
}
}

trace_mm_page_alloc_zone_locked (page, order, migratetype);
return page;
}

The zone passed into this function indicates that the partner algorithm assigns a page box from the memory management area, order is the order of assignment, and Migratetype represents the type of migration. The function prefers __rmqueue_smallest () for memory allocation, which is done through __rmqueue_fallback () if the allocation fails on the specified migration type, and then a different alternate migration list is used for memory allocation. In short, the kernel always makes every effort to ensure that the allocated memory is satisfied.

2.__rmqueue_smallest ()

The implementation of this function is relatively simple, from the current specified allocation order to the highest allocation order in turn to traverse. Select the correct migration queue according to the parameter Migratetype in the list of assigned orders for each traversal. Based on the above qualification, when a list of page box blocks is selected, as long as the list is not empty, you can assign the page box block corresponding to the allocation order.

Once the page box is assigned on the assigned order list that is currently traversed, the page box block is removed from the list by List_entry (). Then remove the Pg_buddy flag from the Home box of the page box block and delete the flag stating that the current page box block is not part of the partner list. And the priveate in the first page box descriptor is set to 0, the field will be saved is the page box block of the allocation order. The above process is done through Rmv_page_order (). Also, update the value of the page box block list Nr_free.

Static inline
struct page *__rmqueue_smallest (struct zone *zone, unsigned int order,
int migratetype)
{
unsigned int current_order;
struct Free_area * area;
struct page *page;

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 (&AMP;PAGE-&GT;LRU);
Rmv_page_order (page);
area->nr_free--;
Expand (Zone, page, order, Current_order, area, migratetype);
return page;
}

return NULL;
}

static inline void Rmv_page_order (struct page *page)
{
__clearpagebuddy (page);
Set_page_private (page, 0);
}

There is also an important function expand () within the __rmqueue_smallest (). The condition for entering this function is that when the requested allocation order is less than the currently selected allocation order Current_order, which means that there is no free page box block in the specified distribution order list, only a larger page box block can be selected. Therefore, the expand () must divide the larger page frame blocks into smaller chunks according to the splitting principle of the partner algorithm.

3.expand ()

The implementation of the split function is also obvious, and it follows the splitting principle of the partner algorithm completely. There are two allocation orders, one is the low specified when the page box is requested, and the high that is selected when traversing in the parent function. The function decrements from the high allocation order to the low, i.e. splits from the larger page box block.

For example, High is 4, while Low is 2. At the first traversal, the page box block of size 16 (assigned order 4) is 2. The following 8 consecutive page box blocks are added to the subordinate list by List_add () (Allocation Order 3), the subordinate list is obtained by reducing the area pointer, and the pointer to the last 8 page box blocks is also obtained through page+size, while the page still points to the original page box block home box. At this point, you also update nr_free for the linked list with a rank of 3, and set some flags for the last 8 page box blocks by Set_page_order ().

The second traversal continues in two of the first 8 page box blocks, adding the last 4 page box blocks to the subordinate list (assigned to 2) that the area points to. On the third traversal, the loop condition is no longer satisfied, so it returns the descriptor Address page of the first 4 page box block Home box.

static inline void expand (struct zone *zone, struct page *page,
int low, int. high, struct Free_area *area,
int migratetype)
{
unsigned long size = 1 << high;
while (High > Low) {
area--;
high--;
Size >>= 1;
vm_bug_on (Bad_range (Zone, &page[size]));
List_add (&AMP;PAGE[SIZE].LRU, &area->free_list[migratetype]);
area->nr_free++;
Set_page_order (&page[size], high);
}
}

static inline void Set_page_order (struct page *page, int order)
{
Set_page_private (page, order);
__setpagebuddy (page);
}

Implementation of the partner algorithm-assigning page boxes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.