分类: LINUX
2008-12-08 16:28:16
页面的分配
alloc_page()
1、 错误处理。当order < MAX_ORDER时,返回空;
2、 返回alloc_pages_current(gfp_mask,order)的返回值
struct *alloc_pages_current( , unsigned )
1、 将pol定义为current的内存池
2、 当gfp状态为等待,并且不在中断的状态时,调用()更新当前运行task的内存状态
3、 当pol为0或者时中断状态或者gfp的状态为__GFP_THISNODE时,将pol的值设置为&default_policy的地址
4、 如果pol的模式为MPOL_INTERLEAVE时,插入一个页面,并返回值
5、 或者返回policy_zonelist(gfp, pol), policy_nodemask(gfp, pol))的返回值。
()该函数为空
in_interrupt()宏指向的时个irq_count()这个函数
()
1、 将定义的zl变量值设置成node_zonelist(nid,gfp)的返回值
2、 将定义的page变量值设置成__alloc_pages(gfp, order, zl)的返回值
3、 如果页面分配成功,并且page_zone(page) 等于zl->_zonerefs[0] –)zone。那么页面增加NUMA_INTERLEAVE_HIT状态。
__alloc_pages_nodemask()
返回__alloc_pages_internal(gfp_mask, order, zonelist, nodemask)的值
static struct zonelist *policy_zonelist(gfp_t gfp, struct mempolicy *policy)
1、 将numa_node_id()的返回值交给变量nd
2、 如果policy类型为MPOL_PREFERRED,并且policy的MPOL_F_LOCAL不存在时,nd赋值为policy->v.preferred_node
3、 如果policy类型为MPOL_BIND,并且gfp的__GFP_THISNODE标志没有被设置,nd已经在policy->v.nodes中。那么将policy->v.nodes的第一个节点赋值给nd
4、 如果policy类型不属于MPOL_INTERLEAVE和以上两个,那么报告错误。
5、 返回node_zonelist(nd,gfp)
页面的释放
free_pages()
如果要求释放的地址有效时,处理无效的虚拟地址,调用__free_pages()释放虚拟地址
__free_pages()
当page计数器原子减操作成功时,如果order为0,则调用free_hot_page()释放掉当前页,或者调用__free_pages_ok(page, order);释放页面
free_hot_cold_page()
1、将当前page的zone赋值给变量zone
2、当前页面的映射的PAGE_MAPPING_ANON存在时,将页面映射置空。当空闲页面检查不成功时,返回
3、当页面不属于高内存段时,错误处理
4、arch_free_page(page, 0);
kernel_map_pages(page, 1, 0);
5、关闭中断并且保存当前状态
6、当cold不为0时,将page->lru增加到,pcp->list尾部,否则,增加到pcp->list的前面
7、将返回所要求的为pageblock_nr_pages block的页的组标记赋值给page->private。
8、pcp计数器加1
9、如果pcp->count的值大于pcp->high的值时,释放页面块,并在pcp->count中减去相应的计数
10、开启中断并恢复状态
11、允许优先级