Chinaunix

标题: 關於remap_file_pages所使用到的zap_pte function疑問 [打印本页]

作者: bboytaiwan    时间: 2012-03-09 09:41
标题: 關於remap_file_pages所使用到的zap_pte function疑問
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。有人有相關的想法嗎?

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

作者: bboytaiwan    时间: 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的動作。

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

謝謝
   
作者: kouu    时间: 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。
作者: bboytaiwan    时间: 2012-03-09 17:11
回复 4# kouu

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

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

謝謝


   
作者: kouu    时间: 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映射产生的)。那么,不管它脏与不脏,也不能写回到文件去。
作者: bboytaiwan    时间: 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使用?

謝謝


   
作者: kouu    时间: 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。
作者: bboytaiwan    时间: 2012-03-10 12:52
kouu 发表于 2012-03-10 11:01
我的理解是,page cache和user space的页表会分别对page有一次reference,reference count不应该=1。


這樣總算理解了,非常感謝你的回答




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2