亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 6557 | 回復(fù): 7
打印 上一主題 下一主題

copy_mm流程解析,順便問兩個問題。。沒看太懂。。 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-06-05 15:28 |只看該作者 |倒序瀏覽
本帖最后由 cluter 于 2011-06-05 15:32 編輯

只講大體流程,不過分追究細節(jié)了,因為細節(jié)我也沒全搞懂,所以只能先整體上把握了。。。 希望大牛指正!
  1. //******************************copy_mm**********************************************
  2. static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
  3. {

  4.         // 1 如果內(nèi)存空間共享,直接增加內(nèi)存描述符mm的引用計數(shù),然后退出
  5.         if (clone_flags & CLONE_VM) {
  6.                 atomic_inc(&oldmm->mm_users);
  7.                 mm = oldmm;
  8.                 goto good_mm;
  9.         }

  10.         // 2 如果內(nèi)存空間不共享,則創(chuàng)建一個新的內(nèi)存空間
  11.         mm = dup_mm(tsk);


  12. good_mm:

  13.         // 3 對于進程來說mm和active_mm指向同一內(nèi)存描述符mm
  14.         //   對于內(nèi)核線程來說,使用active_mm指向當前進程的內(nèi)存描述符mm
  15.         //   內(nèi)核線程不使用線性區(qū)
  16.         tsk->mm = mm;
  17.         tsk->active_mm = mm;
  18.         return 0;

  19. }



  20. struct mm_struct *dup_mm(struct task_struct *tsk)
  21. {

  22.         // 1 為新進程分配一個新的內(nèi)存描述符mm
  23.         mm = allocate_mm();


  24.         // 2 先拷貝父進程內(nèi)存描述符的所有內(nèi)容
  25.         memcpy(mm, oldmm, sizeof(*mm));


  26.         // 3 初始化新內(nèi)存描述符mm中的字段(包括為新進程分配一個新的pgd)
  27.         if (!mm_init(mm, tsk))
  28.                 goto fail_nomem;


  29.         // 4 復(fù)制父進程的線性區(qū)間和頁表
  30.         err = dup_mmap(mm, oldmm);

  31. }



  32. // 1 分配新的vma線性區(qū)并初始化
  33. // 2 如果vma線性區(qū)是file 映射則加入priority-search tree
  34. // 3 把新的vma線性區(qū)加入內(nèi)存描述符mm的red-black tree
  35. // 4 鏈接vma線性區(qū)間
  36. // 5 復(fù)制頁表項
  37. static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
  38. {
  39.         struct vm_area_struct *mpnt, *tmp, *prev, **pprev;
  40.         struct rb_node **rb_link, *rb_parent;
  41.         int retval;
  42.         unsigned long charge;
  43.         struct mempolicy *pol;

  44.         //獲取鎖
  45.         down_write(&oldmm->mmap_sem);
  46.         flush_cache_dup_mm(oldmm);
  47.         /*
  48.          * Not linked in yet - no deadlock potential:
  49.          */
  50.         down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING);

  51.         //初始化mm描述符
  52.         mm->locked_vm = 0;
  53.         mm->mmap = NULL;
  54.         mm->mmap_cache = NULL;
  55.         mm->free_area_cache = oldmm->mmap_base;
  56.         mm->cached_hole_size = ~0UL;
  57.         mm->map_count = 0;
  58.         cpumask_clear(mm_cpumask(mm));
  59.         mm->mm_rb = RB_ROOT;
  60.         rb_link = &mm->mm_rb.rb_node;
  61.         rb_parent = NULL;
  62.         pprev = &mm->mmap;
  63.         retval = ksm_fork(mm, oldmm);
  64.         if (retval)
  65.                 goto out;

  66.         prev = NULL;
  67.         //開始復(fù)制vma線性區(qū)
  68.         for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
  69.                 struct file *file;

  70.                 //線性區(qū)間不允許拷貝
  71.                 if (mpnt->vm_flags & VM_DONTCOPY) {
  72.                         long pages = vma_pages(mpnt);
  73.                         //那么進程地址空間大小就要減去該線性區(qū)間
  74.                         mm->total_vm -= pages;
  75.                         vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
  76.                                                                 -pages);
  77.                         continue;
  78.                 }
  79.                 charge = 0;
  80.                 //IPC共享線性區(qū),檢查是否有足夠的內(nèi)存用于映射
  81.                 if (mpnt->vm_flags & VM_ACCOUNT) {
  82.                         unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
  83.                         if (security_vm_enough_memory(len))
  84.                                 goto fail_nomem;
  85.                         charge = len;
  86.                 }
  87.                 //分配一個新的vma線性區(qū)
  88.                 tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
  89.                 if (!tmp)
  90.                         goto fail_nomem;
  91.                 //復(fù)制內(nèi)容
  92.                 *tmp = *mpnt;
  93.                 INIT_LIST_HEAD(&tmp->anon_vma_chain);
  94.                 pol = mpol_dup(vma_policy(mpnt));
  95.                 retval = PTR_ERR(pol);
  96.                 if (IS_ERR(pol))
  97.                         goto fail_nomem_policy;
  98.                 vma_set_policy(tmp, pol);
  99.                 if (anon_vma_fork(tmp, mpnt))
  100.                         goto fail_nomem_anon_vma_fork;
  101.                 tmp->vm_flags &= ~VM_LOCKED;
  102.                 tmp->vm_mm = mm;
  103.                 tmp->vm_next = tmp->vm_prev = NULL;
  104.                 file = tmp->vm_file;
  105.                 //該vma線性區(qū)是否是文件映射
  106.                 if (file) {
  107.                         //獲取該文件映射對應(yīng)的address_space
  108.                         struct inode *inode = file->f_path.dentry->d_inode;
  109.                         struct address_space *mapping = file->f_mapping;

  110.                         get_file(file);
  111.                         if (tmp->vm_flags & VM_DENYWRITE)
  112.                                 atomic_dec(&inode->i_writecount);
  113.                         spin_lock(&mapping->i_mmap_lock);
  114.                         if (tmp->vm_flags & VM_SHARED)
  115.                                 mapping->i_mmap_writable++;
  116.                         tmp->vm_truncate_count = mpnt->vm_truncate_count;
  117.                         flush_dcache_mmap_lock(mapping);
  118.                         /* insert tmp into the share list, just after mpnt */
  119.                         //新的vma線性區(qū)直接插入priority-search tree
  120.                         //priority-search tree主要用于頁框回收時,釋放所有映射該頁框的頁表項
  121.                         vma_prio_tree_add(tmp, mpnt);
  122.                         flush_dcache_mmap_unlock(mapping);
  123.                         spin_unlock(&mapping->i_mmap_lock);
  124.                 }

  125.                 /*
  126.                  * Clear hugetlb-related page reserves for children. This only
  127.                  * affects MAP_PRIVATE mappings. Faults generated by the child
  128.                  * are not guaranteed to succeed, even if read-only
  129.                  */
  130.                 if (is_vm_hugetlb_page(tmp))
  131.                         reset_vma_resv_huge_pages(tmp);

  132.                 /*
  133.                  * Link in the new vma and copy the page table entries.
  134.                  */
  135.                  //把剛分配的vma線性區(qū)鏈接起來
  136.                 *pprev = tmp;
  137.                 pprev = &tmp->vm_next;
  138.                 tmp->vm_prev = prev;
  139.                 prev = tmp;
  140.                 //把新分配的vma線性區(qū)插入red-black tree
  141.                 __vma_link_rb(mm, tmp, rb_link, rb_parent);
  142.                 rb_link = &tmp->vm_rb.rb_right;
  143.                 rb_parent = &tmp->vm_rb;

  144.                 mm->map_count++;
  145.                 //拷貝頁表項
  146.                 retval = copy_page_range(mm, oldmm, mpnt);

  147.                 if (tmp->vm_ops && tmp->vm_ops->open)
  148.                         tmp->vm_ops->open(tmp);

  149.                 if (retval)
  150.                         goto out;
  151.         }
  152.         /* a new mm has just been created */
  153.         arch_dup_mmap(oldmm, mm);
  154.         retval = 0;
  155. out:
  156.         up_write(&mm->mmap_sem);
  157.         flush_tlb_mm(oldmm);
  158.         up_write(&oldmm->mmap_sem);
  159.         return retval;
  160. fail_nomem_anon_vma_fork:
  161.         mpol_put(pol);
  162. fail_nomem_policy:
  163.         kmem_cache_free(vm_area_cachep, tmp);
  164. fail_nomem:
  165.         retval = -ENOMEM;
  166.         vm_unacct_memory(charge);
  167.         goto out;
  168. }



  169. //************copy_page_range**********************

  170. //調(diào)用流程
  171. copy_page_range
  172.         |
  173.         |
  174.         |
  175. copy_pud_range
  176.         |
  177.         |
  178.         |
  179. copy_pmd_range
  180.               |
  181.               |
  182.         |
  183. copy_pte_range
  184.         |
  185.         |
  186.         |
  187. copy_one_pte


  188. //對于copy_one_pte有兩個重要的地方

  189. // 最開始是關(guān)于如果頁表所映射的頁框已經(jīng)在swap中的處理過程

  190. // 1 如果是copy on write映射,則父子頁表都要寫保護
  191.         /*
  192.          * If it's a COW mapping, write protect it both
  193.          * in the parent and the child
  194.          */
  195.         if (is_cow_mapping(vm_flags)) {
  196.                 ptep_set_wrprotect(src_mm, addr, src_pte);
  197.                 pte = pte_wrprotect(pte);
  198.         }


  199. // 2 如果是共享映射 ,則清空子進程頁表項,屬于請求調(diào)頁
  200.      [size=7][color=Magenta]  //如果是共享映射,為啥不直接負責(zé)頁表項,而是清空子進程頁表項?[/color][/size]

  201.         /*
  202.          * If it's a shared mapping, mark it clean in
  203.          * the child
  204.          */
  205.         if (vm_flags & VM_SHARED)
  206.                 pte = pte_mkclean(pte);
  207.         pte = pte_mkold(pte);[color=Red][size=7]------>這里標記頁表被訪問過是啥意思?[/size][/color]

復(fù)制代碼

評分

參與人數(shù) 1可用積分 +8 收起 理由
Godbach + 8 感謝分享

查看全部評分

論壇徽章:
0
2 [報告]
發(fā)表于 2011-06-05 15:31 |只看該作者
// 2 如果是共享映射 ,則清空子進程頁表項,屬于請求調(diào)頁
       //如果是共享映射,為啥不直接復(fù)制頁表項,而是清空子進程頁表項?

        /*
         * If it's a shared mapping, mark it clean in
         * the child
         */
        if (vm_flags & VM_SHARED)
                pte = pte_mkclean(pte);
        pte = pte_mkold(pte);------>這里標記頁表被訪問過是啥意思?

論壇徽章:
4
酉雞
日期:2014-03-21 23:19:50獅子座
日期:2014-08-01 22:11:40酉雞
日期:2015-01-10 21:31:442015年辭舊歲徽章
日期:2015-03-03 16:54:15
3 [報告]
發(fā)表于 2011-06-05 16:42 |只看該作者
pte_mkclean/pte_mkold都是修正父進程的pte,然后拷貝到子進程的頁表中,你的理解沒錯.
mkclean不等于清空

論壇徽章:
0
4 [報告]
發(fā)表于 2011-06-08 09:26 |只看該作者
本帖最后由 懂醫(yī)術(shù)的廚師 于 2011-06-08 09:27 編輯

1. copy_mm一開始就判斷是否CLONE_VM,如果是則加一。否則拷貝,直到copy_page_range,此時以明確不再share,如果發(fā)現(xiàn)share,則清空子進程的pte
2.清空pte并不是暴力刪除這個條目,可能以后還會用呢,所以直接mark為clean就行了,lazy work

論壇徽章:
0
5 [報告]
發(fā)表于 2011-06-08 11:59 |只看該作者
謝謝樓上2位。。。

論壇徽章:
0
6 [報告]
發(fā)表于 2011-06-08 12:00 |只看該作者
回復(fù) 4# 懂醫(yī)術(shù)的廚師


    mkold是標記頁表項已經(jīng)被訪問過?這個用意何在?和頁框回收有關(guān)系?

論壇徽章:
0
7 [報告]
發(fā)表于 2011-06-08 12:11 |只看該作者
回復(fù) 6# cluter

和tlb,proc統(tǒng)計等有關(guān),簡單貼段:
int ptep_clear_flush_young(struct vm_area_struct *vma,
{
    young = ptep_test_and_clear_young(vma, address, ptep);
    if (young)
      flush_tlb_page(vma, address);
...

論壇徽章:
0
8 [報告]
發(fā)表于 2011-06-08 21:30 |只看該作者
回復(fù) 7# 懂醫(yī)術(shù)的廚師


    謝謝LS解答。。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP