page reclaim 05:page count
2017-02-07
1. 问题引入
linux-3.10.86/mm/vmscan.c
static inline int is_page_cache_freeable(struct page *page)
{
/*
* A freeable page cache page is referenced only by the caller
* that isolated the page, the page cache radix tree and
* optional buffer heads at page->private.
*/
return page_count(page) - page_has_private(page) == 2;
}
为何是== 2?
2. 解
调用路径:
shrink_inactive_list
|--lru_add_drain
|--isolate_lru_pages
| |--get_page_unless_zero //引用计数
|--shrink_page_list (shrink_page_list不会被shrink_active_list调用.)
| |--pageout
| | |--is_page_cache_freeable
2.1 isolated the page
略
2.2 buddy system
注释中提到"the page cache radix tree"的引用计数, 这个注释并不准确, 应该是从buddy system分配产生的引用计数.
buddy system的get:
page_cache_alloc_cold -> __alloc_pages_nodemask
| |--get_page_from_freelist
| | |--buffered_rmqueue
| | | |--prep_new_page
| | | | |--set_page_refcounted -> set_page_count(page, 1);
并不是radix tree的get的理由如下:
以dogenericfile_read 为例, 看下page cache的get:
do_generic_file_read
|--no_cached_page: page_cache_alloc_cold -> __alloc_pages_nodemask
| |--get_page_from_freelist
| | |--buffered_rmqueue
| | | |--prep_new_page
| | | | |--set_page_refcounted -> set_page_count(page, 1);
|--add_to_page_cache_lru
| |--add_to_page_cache -> add_to_page_cache_locked
| | | |--page_cache_get //引用计数A
| | | |--radix_tree_insert
| |--lru_cache_add_file -> __lru_cache_add
|--readpage: mapping->a_ops->readpage(filp, page)
|--ret = actor(desc, page, offset, nr);//比如file_read_actor()
|--page_cache_release(page); //引用计数B
使用完后, 修改引用计数, 故这里对引用计数没有影响.
lru的计数呢?
答:加入pagevec中会get page, 清空pagevec放入lru时, 会put page.
2.3 buffer_head
若pagehasprivate()返回1, 则page_count为3
buffer_head时的get page:
grow_dev_page
|--find_or_create_page
|--alloc_page_buffers
|--link_dev_buffers(page, bh) -> attach_page_buffers
| |--page_cache_get
| |--set_page_private
|--page_cache_release(page); //和find_or_create_page中的get 对应
本文地址: https://awakening-fong.github.io/posts/mm/reclaim_05_page_count
转载请注明出处: https://awakening-fong.github.io
若无法评论, 请打开JavaScript, 并通过proxy.
blog comments powered by Disqus