buddy之expand函数
主要内容
本文以图示方式展示buddy系统expand()算法流程,供备忘。
buddy系统从free_area[current_order]中分配页面(块)后,会调用page_alloc.c:expand()函数试图将多分配的页(块)回给buddy。
- 内核版本 4.19.90
业精于勤荒于嬉
过程图示
初始状态
上图中 :请求分配order=2的块,实际分配了order=5的块,expand负责将本次多分配的部分内存块返还到buddy中。
结束状态
迭代过程
源码
mm/page_alloc.c
/*
* The order of subdivision here is critical for the IO subsystem.
* Please do not alter this order without good reasons and regression
* testing. Specifically, as large blocks of memory are subdivided,
* the order in which smaller blocks are delivered depends on the order
* they're subdivided in this function. This is the primary factor
* influencing the order in which pages are delivered to the IO
* subsystem according to empirical testing, and this is also justified
* by considering the behavior of a buddy system containing a single
* large block of memory acted on by a series of small allocations.
* This behavior is a critical factor in sglist merging's success.
*
* -- nyc
*/
//核心函数,释放剩余部分的页到buddy合适的zone->free_area[xxx_order]中去
//@page 分配成功的内存块的头页
//@order 请求分配的内存大小(1<<order)
//@current_order 实际分配内存时,从1<<current_order块中分配。也就是@page所对应的内存块
//@area @current_order对应的zone->free_area[current_order]链表
//@migratetype 请求分配的页面类型
//expand(zone, page, order, current_order, area, migratetype);
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) { //代表仍然有部分内存块需要释放到buddy
area--;
high--;
size >>= 1;//size代表分配的内存块大小,size/2代表需要将size/2的块返还到buddy
VM_BUG_ON_PAGE(bad_range(zone, &page[size]), &page[size]);
/*
* Mark as guard pages (or page), that will allow to
* merge back to allocator when buddy will be freed.
* Corresponding page table entries will not be touched,
* pages will stay not present in virtual address space
*/
if (set_page_guard(zone, &page[size], high, migratetype))
continue;
//page[size]标识后半块的起始page
list_add(&page[size].lru, &area->free_list[migratetype]);
area->nr_free++;
//调整后半块的order,此时满足size==2<<high
set_page_order(&page[size], high);
}
}