https://zhuanlan.zhihu.com/p/421298579从新增、删除、修改为切入点,讨论file lru的转换规则,下面进行了简单总结。
新增:
调用read/write/mmap生成的新page,默认加到file inactive lru的表头,当一个page多次访问时或者workingset active(下文会介绍)时会加到file active lru 表头。
(代码参考:vfs_read -> generic_file_read_iter -> filemap_read -> filemap_get_pages -> filemap_create_page -> add_to_page_cache_lru -> lru_cache_add -> __pagevec_lru_add -> add_page_to_lru_list
Mmap的page_fault -> ext4_file_map/xfs_file_mmap -> filemap_fault -> pagecahce_get_page -> add_to_page_cache_lru -> lru_cache_add -> __pagevec_lru_add -> add_page_to_lru_list)删除:
1) 当内存回收时,会遍历所有的inactive的lru,只取各个链表末尾32个page,将其回收,但是如图5会有一些特别的页不能被回收。
(代码参考:同步/异步回收 -> shrink_node -> shrink_node_memcg -> shrink_lruvec -> shrink_list -> shrink_inactive_list -> shrink_page_list)2) 当内存回收时,如果inactive lru长度不足,那么将扫描active lru末尾32个页添加到inactive lru头部。
(代码参考:同步/异步回收 -> shrink_node -> shrink_node_memcg -> shrink_lruvec -> shrink_list -> shrink_active_list -> move_pages_to_lru)修改:
1) 多次访问的页会从inactive lru转移到active 表头。
(代码参考:vfs_read -> generic_file_read_iter -> filemap_read -> mark_page_accessed -> activate_page -> __ activate_page -> add_page_to_lru_list)2) 回写后的脏页会转移到inactive末尾。
(代码参考:脏页回写 -> end_page_writeback -> rotate_reclaimable_page -> pagevec_move_tail_fn -> add_page_to_lru_list_tail)3) Pageref_keep的页会放到inactive表头,Pageref_active的页会转移到active lru表头。
(代码参考:shrink_inactive_list -> shrink_page_list -> page_check_references)