kernel阅读手记之页面分配和释放

页面的分配

alloc_page()
1、  错误处理。当 order < MAX_ORDER 时,返回空;
2、  返回 alloc_pages_current (gfp_mask , order) 的返回值

struct page *alloc_pages_current (gfp_t gfp , unsigned order )
1、  将 pol 定义为 current 的内存池
2、  当 gfp 状态为等待,并且不在中断的状态时,调用 cpuset_update_task_memory_state () 更新当前运行 task 的内存状态
3、  当 pol 为 0 或者时中断状态或者 gfp 的状态为 __GFP_THISNODE 时,将 pol 的值设置为 &default_policy 的地址
4、  如果 pol 的模式为 MPOL_INTERLEAVE 时,插入一个页面,并返回值
5、  或者返回 policy_zonelist(gfp, pol), policy_nodemask(gfp, pol)) 的返回值。

cpuset_update_task_memory_state()该函数为空
in_interrupt()宏指向的是个irq_count()这个函数

alloc_page_interleave()

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、允许优先级

你可能感兴趣的:(struct)