Linux内核伙伴系统中页面释放,主函数为free_pages()
一、上层操作
/*用虚拟地址进行释放*/
void free_pages(unsigned long addr, unsigned int order)
{
if (addr != 0) {
VM_BUG_ON(!virt_addr_valid((void *)addr));
__free_pages(virt_to_page((void *)addr), order);/*具体的释放函数*/
}
}
/*释放页面*/
void __free_pages(struct page *page, unsigned int order)
{
if (put_page_testzero(page)) {/*count值减一为0时释放*/
/*调试*/
trace_mm_page_free_direct(page, order);
if (order == 0)
free_hot_page(page);/*释放单个页面*/
else
__free_pages_ok(page, order);
}
}
二、释放单个页面
释放单个页面free_hot_page()调用free_hot_cold_page()函数
static void free_hot_cold_page(struct page *page, int cold)
{
struct zone *zone = page_zone(page);
struct per_cpu_pages *pcp;
unsigned long flags;
int migratetype;
int wasMlocked = __TestClearPageMlocked(page);
/*调试代码*/
kmemcheck_free_shadow(page, 0);
if (PageAnon(page))
page->mapping = NULL;
if (free_pages_check(page))
return;
if (!PageHighMem(page)) {
debug_check_no_locks_freed(page_address(page), PAGE_SIZE);
debug_check_no_obj_freed(page_address(page), PAGE_SIZE);
}
/*x86下为空*/
arch_free_page(page, 0);
/*调试用*/
kernel_map_pages(page, 1, 0);
/*获得zone对应cpu的pcp*/
pcp = &zone_pcp(zone, get_cpu())->pcp;
/*获得页面的migratetype*/
migratetype = get_pageblock_migratetype(page);
set_page_private(page, migratetype);/*设置私有位为参数*/
local_irq_save(flags);/*保存中断*/
if (unlikely(wasMlocked))
free_page_mlock(page);
__count_vm_event(PGFREE);
/*
* We only track unmovable, reclaimable and movable on pcp lists.
* Free ISOLATE pages back to the allocator because they are being