- 论坛徽章:
- 0
|
active_list中满足 if(page_count(p) == 1 && !p->buffers)的页p->mapping 一定不等于NULL
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I've got it! All guys Come on to share and comment it !
It's based on kernel-2.4.8.
我们一直都忽略了active_list中到底存放的是些甚么属性的页,而这不能凭空假设。active_list在kswapd运行之初是空
的,是在do_try_to_freepages函数中将页从inactive_dirty_list中删除而逐渐插入的,这是一个关键,到底怎样的页才
能插入到active_list中呢?
Part A:
当一个页被文件映射或被作为块缓存后,它同时也被加入到inactive_dirty_list中,所以加入到inactive_dirty_list中的页面page满足以下属性:
if(page->buffers && !page->mapping ) page_count(page) >= 1
else if(page->buffers && page->mapping) page_count(page) >= 2
else if(page->mapping && !page->buffers ) page_count(page) >= 1
所以你就会发现在kswapd尚无开始进行交换时,cat /proc/meminfo中的InActive 已是若干大的值而SwapCached, 和Active仍为零,直到kswapd发现系统内存紧缺
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Part B:
在kswapd发现内存不足时调用do_try_to_freepages
i )
page_launder将遍历inactive_dirty_list链表,将其中的最近被访问过或者被进程映射过的页面加入到
active_list中,此时active_list中的页面
是"pagecache或swapcache或buffercache"中近来被进程映射(page_count(page) >
(!page->buffers?1:2) )的页或近来被访问Referenced过的页.
以下给出相关的代码:/2.4.8/
if (PageReferenced(page) || (!page->buffers && page_count(page) > 1) || page_ramdisk(page)) {
del_page_from_inactive_dirty_list(page);
add_page_to_active_list(page);
page->age = PAGE_AGE_START;
continue;
}
if(page->buffers){
......
if (page->mapping && page_count(page) > 2) {
add_page_to_active_list(page);
}
......
}
如果active_list中的页的引用计数蜕化到page_count(page) ==
1(page->buffers==0)则最后一个用户肯定是pagecache或swapcache,若page->buffer!=0,
则肯定是pagecache或swapcache与buffercache的组合page_count(page) == 2
ii )
在page_launder之后do_try_to_freepages将调用refill_inactive,
do_try_to_freepages--->refill_inactive--->refill_inactive_global
或refill_inactive_zone---->swap_out--->try_to_swap_out将当前进程的地址空间中合适
的页插入到inactive_dirty_list中,插入后的页即链表中的页满足(简单起见,这儿我们暂不考虑buffers块缓冲页的情况,如考虑只
需将相应的数值后+1):
对于脏的非文件缓冲页则创建新的swapcache页,在add_swap_cache时get_page加1,然后
page_cache_release时又减1,所以count仍然等于之前的页引用计数,但用户已由原来的进程变成了swapcache,即假设在
swap_out之前有4个进程映射到该页,之后则有另外三个进程+swapcache映射到该页,仍然是4。新创建的swapcache页
page_count
>=2,若等于2即该页原仅被一个进程映射,则加入到inactive_dirty_list中,随后page_cache_release页计数
减1后等于1,加入inactive链表的页的唯一属主为swapcache.
脏的文件缓冲页(!PageSwapCache(p) &&
p->mapping)在swap_out之前有大于等于2的页映射计数,如果等于2即原被一个进程映射,另一个映射属主是pagecache自
身, 则该页被加入到inactive链表中,若大于2则递减引用计数,取消当前进程映射,但不加入到inactive链表中
所以, try_to_swap_out调用结束后
"inactive_dirty_list中除了先前PartA中已经存放其中的页之外还存放了新创建的swapcache页和一般的非
swapcache的pagecache页且映射计数为1,若buffer为该页属主之一的话,则计数为2".
iii )
refill_inactive_global或refill_inactive_zone在调用swap_out之后会调用refill_inactive_scan将遍历active_list链表中的页 ,
将最近被访问过的页age_up,否则age_down,对于后者并检查该页是否age == 0,如果为零,检查该页的页引用计数是否 满足下列条件,满足则加入到inactive_dirty_list中。在active_list中的页面满足
page->mapping && page->buffers?page_count(page)>2:1.
以上属性由PartB--i)得到。若当前检查其中的页时页属性不满足则必然将它置入inactive_dirty_list链表中。
if(page_count(page) buffers ? 2 : 1)) {
deactivate_page_nolock(page);
page_active = 0;
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/98377/showart_2056304.html |
|