1.page数据结构
page数据结构可以分为四个部分:
mapping成员:
mapping表示页面所指向的地址空间,内核中有两个不同的地址空间:
- 文件映射页面(在读取文件时,将文件内容数据与存储介质区关联起来)
- 匿名映射(指向匿名页面地址空间数据结构
anon_vma
)
2._refount
的应用
_refount
表示内核中引用该页面的次数:
>0
表示页面已被分配且正在被使用,暂时不释放。=0
表示页面空闲或即将被释放。
使用内核中get_page
使_refount
加1,put_page
使_refount
减1。
_refount
用于跟踪页面的使用情况:
-
初始状态下,空闲页面的
_refount
是0。 -
alloc_page
成功分配页面后,_refount
应该为0,然后设置页面的_refount
为1。 -
加入LRU,页面被kswapd使用,
_refount
会加1。
-
映射到其他进程PTE,
_refount
加1。
-
页面
private
成员指向私有数据。- 对于
PG_swapable
的页面,__add_to_swap_cache()
函数会增加_refount
- 对于
PG_private
的页面,buffer_migrate_page()
函数会增加_refount
- 对于
3._mapcount
的应用
_mapcount
表示页面被多少个PTE映射,有多个用户进程地址空间同时映射到一个物理页面的情况,_mapcount
主要用在RMAP系统中。
-
_mapcount
为-1,表示没有PTE映射到页面 -
_mapcount
为0,表示只有父进程映射到页面。匿名页面刚分配时,_mapcount
初始化为0
-
_mapcount
大于0,表示除了父进程还有其他进程映射到这个页面
4.页锁
page数据结构成员PG_locked
为页锁,lock_page()
函数由于申请页锁,如果页锁被其他进程占用,就会睡眠等待。
5.mapping
的应用
mapping
指向页面对应存储设备的地址空间:
- 匿名页面:
mapping
指向VMA
的anon_vma
数据结构。 - 交换高速缓存页面:
mapping
指向交换分区的swapper_spaces
- 文件映射页面,
mapping
指向文件所属的address_space
数据结构,包含文件所属介质的相关信息。
6.相关接口函数
-
page_mapping()
函数page_mapping()
返回page数据结构中mapping
成员指向的地址空间address_space
数据结构- 匿名页面:
anon_vma
数据结构指向RMAP
机制用的数据结构,没有指向对应的存储介质,所以page_mapping()
返回NULL
。 - 交换高速缓存页面:通过
swap_address_space()
宏返回分区的address_space
- 文件映射页面:返回时把低二位清零,低二位用于确定该页面是匿名页面还是KSM页面。
- slab分配器页面:返回NULL
- 匿名页面:
-
page_mappde()
函数page_mappde()
判断页面是否有映射到用户PTE,判断_mapcount
是否大于或等于0