Why do we need page frame?
实际 page frame 只是 kernel 的一个 struct,用于:
- 记录:由其包含的 physical page 地址(其实还是virtual addr)
- 记录:该page 所属的 memeory object(即 vm_area_struct/bss… 所指向的);以及该page 的 page_num
- 第一条“由其包含”表明了,OS需要一个结构体来管理所“征用”的physical page,这个结构体就是 page frame
- 注意:page frame 中的page 不一定都在 physical memory 中,也有可能被 page out 到了 disk。前者称为 resident page。
1. pframe_init()
使用物理内存之前的准备工作,开机时?
初始化与 pframe 有关的量:
- alloc_list
- pinned_list
- pframe_allocator
- pageout deamon
2. pframe_shutdown()
停止使用物理内存之后的清理工作,关机时?
- 停止 pageout deamon
- 清理及 free 所有 page
3. pframe_get_resident()
获得“驻足内存的pframe”,based on mmobj & pagenum; 如果pframe 不再内存中,返回NULL
4. pframe_alloc()
为 mmobj、pagenum 指定的 page 分配物理内存
5. pframe_lookup()
实际上就是执行 pframe_get(),
6. pframe_get()
#参见page\_fault()
:
https://caomingkai.github.io/2018/04/18/VM-Page-Table-Page-Fault-Hander/
根据 ‘mmobj & pagenum’ 得到 pframe
- 如果物理内存中已有该page,直接返回
- 如果物理内存中没有该page,allocate 新的,并(有可能从disk)fill 进内容
- 先判断由 ‘mmobj & pagenum’ 指明的pframe 是否存在于内存中,by calling pframe_get_resident()
- 如果存在,继续判断 pframe 是否 busy(因为有可能被 pageout deamon 操作)
- if busy 则 sleep;醒来时再回到第1步,判断pframe是否存在于物理内存中
- if not busy,直接返回 pframe
- 如果不存在,则创建新的pframe
- 先判断是否需要启动 pageout deamon 释放部分物理内存,需要的话就唤醒 deamon
- 然后分配pframe空间, pframe_alloc(o,pagenum);注意返回值ERROR
- 再向刚获得的pframe中添加内容, pframe_fill();注意返回值ERROR
- 如果存在,继续判断 pframe 是否 busy(因为有可能被 pageout deamon 操作)
7. pframe_migrate()
将pframe 移到父节点;缩短 shadow object tree 的高度(在某个mmobj被清除的时候)
8. pframe_fill()
调用 specific mmobj 的 fillpage() 真正实现将外部数据读入物理内存
9. pframe_pin()
对该 pframe 锁定 pin down,防止被 pageout
- 判断该 pframe 的 pf_pincount 是否为“0”
- 如果==0,表明该 pframe page 在 allo_chain上
- 从原来 chain 卸下来
- nallocated–
- 加入 pinned_chain 中
- npinned++
- pf->pf_pincount++
- 如果 != 0,表明该 pframe page 已经在 pinned_chain上了
- 只需要 pf->pf_pincount++ 即可
- 如果==0,表明该 pframe page 在 allo_chain上
10. pframe_unpin()
将该 pframe 解锁,向 pageout deamon 开放
- 首先更新 pf_pincount: pf_pincount–;
- 判断该 pframe 的 pf_pincount 目前是否为“0”
- 如果==0,那么
- 从 pinned_chain 中卸下来
- npinned–
- 加入 alloc_chain 中
- nallocated++
- 如果 !=0, 那么啥也不做
- 如果==0,那么
11. pframe_dirty()
对 pframe(仅指file_obj,shadow、anony 无法pageout)进行更改之前,将该page设置为 DIRTY,待 pageout deamon 回收的时候检查到DIRTY时,会将page的内容更新到 disk 上