标题: linux内存管理之伙伴系统分析(大内存分配)(续三) [打印本页] 作者: thewayma 时间: 2009-10-09 22:18 标题: linux内存管理之伙伴系统分析(大内存分配)(续三) min /= 2;
if (can_try_harder)
min -= min / 4;
min += (1protection[alloc_type];
if (z->free_pages
continue;
page = buffered_rmqueue(z, order, gfp_mask);
if (page)
goto got_pg;
}
do_retry = 0;
if (!(gfp_mask & __GFP_NORETRY)) {
if ((order
do_retry = 1;
if (gfp_mask & __GFP_NOFAIL)
do_retry = 1;
}
if (do_retry) {
blk_congestion_wait(WRITE, HZ/50);
goto rebalance;
}
nopage:
if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit()) {
printk(KERN_WARNING "%s: page allocation failure."
" order:%d, mode:0x%x\n",
p->comm, order, gfp_mask);
dump_stack();
}
return NULL;
got_pg:
zone_statistics(zonelist, z);
kernel_map_pages(page, 1
return page;
}
从上面的分配过程,我们可以看到.整个分配过程是非常繁杂的,不过,大部份情况下,在第一次循环下就可以请求到内存了.上面这段代码中有一个重要的函数try_to_free_pages(),由于涉及的东西比较多,在分析完slab,swap address_space之后再对它进行详细的分析.请关注本站的更新.
到这里,对alloc_pages有个大概的了解,从上面的代码可以看到,从相应的zone分配内存的接口是buffered_rmqueue().代码如下:
static struct page *
buffered_rmqueue(struct zone *zone, int order, int gfp_flags)
{
unsigned long flags;
struct page *page = NULL;
int cold = !!(gfp_flags & __GFP_COLD);
if (order == 0) {
//单页面的分配
//每个cpu都维持着一个”冷”,”热”页面的内存池
struct per_cpu_pages *pcp;