l 如果页面是进程空间映射并且页面映射地址非空,则调用()移除该页面的页表映射;
l 如果页面为dirty页面并且无引用、交换可写、且是fs文件系统映射,调用()写出该页面 。
3) 循环结束,把局部链表中的页面移回到链表中;
4) 返回回收页面数 。
每个页面帧处理后只有三种结果:
通过调用free_code_page()页面被释放到伙伴系统中,页面被有效回收;
页面没有回收,被重新插入到page_list链表中,并且认为该页面在将来可能会被再次回收,因而清除PG _active标志,以便在后面加入到inactive链表中;
页面没有回收,被重新插入到page_list链表中,并且认为该页面在可预见的将来不会被再次回收,因而设置PG _active标志,以便在后面加入到active链表中
回收一个匿名页面时,该页面必须添加到交换缓存中,交换区中必须为其预留一个新页槽 。如果页面在某些进程的用户态地址空间中,()调用定位所有执向该页面帧的进程PTE项,只有返回成功时才继续回收;如果页面是dirty状态,必须要写到磁盘上才能回收,这需要调用()函数,回收只有在()很快完成写操作或者不必进行写操作时才继续进行;如果页面保护VFS ,则调用()释放 heads 。
最后如果上面都进展顺利的话, ()函数检查页的引用计数:如果值正好为2,则一个为页面缓存或交换缓存,另一个是PFRA自身(()函数中增加该值) 。这种情况下,该页面可以回收,并且它不为dirty 。根据页面PG 标志,页面从页面缓存或交换缓存中移除;然后调用() 。
换出页面
( page * page, gfp_t )换出操作首先是为页面分配交换页槽,并分配交换缓存;步骤如下:
get_swap_page()为换出页面预留交换槽位;
调用__add_to_swap_cache()传入槽索引、页描述符和gfp标志将页面加到交换缓存中,并标记为dirty;
设置页面PG _uptodate和PG_dirty标志,以便shrink_inactive_page()能够强制将页面写到磁盘上;
返回;
*( page page, int ),换出操作第二步,在后面调用,该函数查找所有用户页表中指向该匿名页帧的页表项,并在PTE中设置换出标志 。
()换出操作第三步将dirty页面写到磁盘:
检查页面缓存或交换缓存中的页,并查看该页面是否近被页面缓存或交换缓存占有;如果失败,返回PAGE_KEEP 。
检查address_space对象的writepage方法是否定义,如没有返还PAGE_ACTIVATE;
检查当前进程是否可以发送写请求到当前映射地址空间对象对应的块设备上请求队列上 。
SetPageReclaim(page)设置页面回收标志;
调用mapping->a_ops->writepage(page, &wbc)进行写操作,如果失败则清除回收标志;
如果PageWriteback(page)失败,页面没有写回,则清除回收标志ClearPageReclaim(page);
返回成功;
对于交换分区,的实现函数是(),该函数流程如下:
检查是否有其他进程引用该页面,如果没有,从交换缓存中移除该页面返回0;
get_swap_bio()分配初始化bio描述符,该函数从交换页标志中找到交换区,然后遍历交换扩展链表找到页槽的起始磁盘分区 。bio描述符包含对一个页面的请求,并设置完成方法为end_swap_bio_write() 。
set_page_writeback(page)设置页面writeback标志,unlock_page()该页面解锁;
submit_bio(rw, bio)向块设备提交bio描述符进行写操作;
- C/C++内存泄漏原因分析与应对方法
- 5 c语言调用Linux的sleepy函数,Linux设备驱动程序学习
- 内存管理专题04 伙伴分配器原理
- linux内核异步内存回收的另一个思路:基于冷热文件的冷热区域精准的回收冷文件页
- 内存换出和缓冲区释放
- Linux系统下QT的安装与配置
- java 运行.jnlp文件,在Linux系统上执行/打开JNLP文件的方法
- Linux基础入门知识
- Linux文件:/etc/fstab
- htpasswd linux