免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2851 | 回复: 8

關於remap_file_pages所使用到的zap_pte function疑問 [复制链接]

论坛徽章:
0
发表于 2012-03-09 09:41 |显示全部楼层
function列在下面,我大概敘述一下對這個function的理解。
26 static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
27                         unsigned long addr, pte_t *ptep)
28 {
29         pte_t pte = *ptep;
30
31         if (pte_present(pte)) {
32                 struct page *page;
33

要把page還回去,要先做flush的動作

34                 flush_cache_page(vma, addr, pte_pfn(pte));

取出pte的值,清除pte,同時也要記得清除tlb相對應的欄位

35                 pte = ptep_clear_flush(vma, addr, ptep);

得到pte相對應pfn的page

36                 page = vm_normal_page(vma, addr, pte);
37                 if (page) {
38                         if (pte_dirty(pte))
39                                 set_page_dirty(page);

移除在這個page上面相對應的map

40                         page_remove_rmap(page);

把page_cache釋放掉:裡面是否要判斷share或者是private,如果是share,是不是還要寫回
file去 ?


41                         page_cache_release(page);
42                         update_hiwater_rss(mm);
43                         dec_mm_counter(mm, file_rss);
44                 }
45         } else {
46                 if (!pte_file(pte))
47                         free_swap_and_cache(pte_to_swp_entry(pte));
48                 pte_clear_not_present_full(mm, addr, ptep, 0);
49         }
50 }
關鍵在於page_cache_release這行,是不是要進行寫回檔案系統的動作,原因是page cache有可能是share。
但是在這個function裡面找不到相關寫回file system的動作,只有釋放回去per cpu cache。有人有相關的想法嗎?

謝謝

论坛徽章:
0
发表于 2012-03-09 11:07 |显示全部楼层
我的理解是:
进程的页表上建立了到某个page的映射,假设这个page属于某个文件的page cache,它被挂在该文件所对应的radix树上。(如果这个page是脏的,并且page还在radix树上,那么肯定是share映射。否则page早已经被COW了。)
zap_pte要做的事情是取消这个映射,而不是把这个page从radix树上拿掉。内核另有页面回收机制将这些page从radix树上,并将脏page写回磁盘。

论坛徽章:
0
发表于 2012-03-09 14:38 |显示全部楼层
回复 2# kouu

其實我原本的想法也是這樣,但是在

page_cache_release --> put_page --> __page_cache_release --> free_hot_page --> free_hot_cold_page

看到會把page加回per-cpu page。

1124         if (cold)
1125                 list_add_tail(&page->lru, &pcp->lists[migratetype]);
1126         else
1127                 list_add(&page->lru, &pcp->lists[migratetype]);
1128         pcp->count++;

貌似page已經被釋放。因此我才會想說怎麼沒有看到寫回file system的動作。

不知道各位大牛有何想法?

謝謝
   

论坛徽章:
0
发表于 2012-03-09 16:43 |显示全部楼层
put_page是为page减引用,page->_count--。
只有在put_page_testzero()返回真,也就是page->_count减为0的情况下,才能释放page。

而page被加入到page cache的时候,当然page cache是要对它加引用的。
do_generic_file_read -> add_to_page_cache_lru -> add_to_page_cache -> add_to_page_cache_locked -> page_cache_get -> get_page

所以zap_pte的时候并不会触发__page_cache_release。

论坛徽章:
0
发表于 2012-03-09 17:11 |显示全部楼层
回复 4# kouu

是否可以請問一下,今天即使reference count = 0,有可能page會是dirty的情況,如果貿然回收,沒有寫回file system,會不會因此產生資料丟失的問題。

我現在的理解在於沒有看到判斷page是否為dirty,如果是dirty,需要寫回file system的代碼。

謝謝


   

论坛徽章:
0
发表于 2012-03-09 18:03 |显示全部楼层
1、page cache是文件在内存中的镜像,进程要映射一个文件中的page,则这个page必定是在page cache上的。
2、page在page cache上,则page cache必定有对它的引用。
基于以上两点,进程在取消到一个page cache中的page的映射的时候,ref count不会减为0。
反过来,如果ref count减为0,说明page并不在page cache上,也就是说这个page并不属于对某个文件的镜像(比如可能是由于private映射产生的)。那么,不管它脏与不脏,也不能写回到文件去。

论坛徽章:
0
发表于 2012-03-10 09:16 |显示全部楼层
回复 6# kouu

謝謝你的詳細解釋,我大概有點理解。

只是覺得奇怪的點,如果今天我在user space mmap一塊share的address space(這時他的reference count應該=1)。

之後拿這塊space去做remap_file_pages的system call。在原代碼的put_page_testzero()會將其減為零。

這樣scenario,為什麼不會發生? 還是share的address space不能拿來做remap使用?

謝謝


   

论坛徽章:
0
发表于 2012-03-10 11:01 |显示全部楼层
bboytaiwan 发表于 2012-03-10 09:16
如果今天我在user space mmap一塊share的address space(這時他的reference count應該=1)

我的理解是,page cache和user space的页表会分别对page有一次reference,reference count不应该=1。

论坛徽章:
0
发表于 2012-03-10 12:52 |显示全部楼层
kouu 发表于 2012-03-10 11:01
我的理解是,page cache和user space的页表会分别对page有一次reference,reference count不应该=1。


這樣總算理解了,非常感謝你的回答
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP