免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2101 | 回复: 8
打印 上一主题 下一主题

[内存管理] 内存页的mapcount和反向映射的链表长度是完全一样长吗? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-06-19 15:55 |只看该作者 |倒序浏览
按照理解,page的mapcount就是页面映射到页表的个数,应该就是反向映射的链表长度大小或者优先树的节点总数。但是kernel代码为什么要重复判断呢:

static int page_referenced_anon(struct page *page,
                                struct mem_cgroup *memcg,
                                unsigned long *vm_flags)

        。。
        mapcount = page_mapcount(page);
        //这里遍历反向映射的节点
        list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
                struct vm_area_struct *vma = avc->vma;
                referenced += page_referenced_one(page, vma, address,
                                                  &mapcount, vm_flags);
                //这里还要判断mapcount的数量,这不是重复吗?
                if (!mapcount)
                        break;
        }
。。


对于file mapping的reference查找函数page_referenced_file,也是要做同样的判断。

对于linux kernel都是代码精巧,关键函数都没有废代码,这里为啥要重复判断呢?有什么特殊情况吗?

论坛徽章:
0
2 [报告]
发表于 2014-06-19 17:04 |只看该作者
回复 1# kerryxi


   
按照理解,page的mapcount就是页面映射到页表的个数,应该就是反向映射的链表长度大小或者优先树的节点总数


你理解错了后一句话。。。用匿名映射举例:在fork子进程时,拷贝父进程vma时,会把子进程的vma加入到父进程vma的anon_vma链表中的各个
anon_vma的区间树(红黑树的变体)中去。所以,你试想,某一个pte已经COW出去了,所以该pte原来映射的那个父子进程共享
的那个页面的mapcount值就要减1。但因为该vma中其他pte仍然跟父进程共享页面,所以它还在父进程anon_vma的区间树中,
所以当你正好检查的是COW了的那个页面的mapcount,你到anon_vma的区间树中去搜vma,会碰到上面说的那个pte,会发现
他里面存放的页帧已经不是这个页面了,so。。。。

论坛徽章:
0
3 [报告]
发表于 2014-06-19 17:14 |只看该作者
回复 1# kerryxi


   page_referenced_one函数调用传入的是&mapcount,在该函数里如果找到了对应的pte,mapcount值会减1的。。。

论坛徽章:
0
4 [报告]
发表于 2014-06-19 17:28 |只看该作者
回复 2# njuzhyf


    真是高明啊。那么这样统计的anon_vma的节点是不是都是一样呢?  COW的pte不一定就在mapcount之后啊?之前进行page_referenced_one处理的才是真正reference的页面吗?

论坛徽章:
0
5 [报告]
发表于 2014-06-19 17:35 |只看该作者
回复 4# kerryxi


我看不懂你说的     

论坛徽章:
0
6 [报告]
发表于 2014-06-20 09:34 |只看该作者
回复 5# njuzhyf


    似乎明白又不明白,我再看了一下相关代码,仍以anon为例,2点理解:
1. 在fork进程后,old page的anon_vma链表应该是parent vma和child vma的两个vma引用。这个应该没理解错吧?
2. 子进程在对应其中一个page写操作后,触发page cow,old page(parent的页面)的mapcount的引用计数会减一,但是old page的反向映射链表仍然是parent vma和child vma的两个vma引用。没看到do_wp_page有去除child vma的操作,对吗? 如果是的话,old_page的anon_vma链表中child vma节点什么时候去除呢?

谢谢!

论坛徽章:
0
7 [报告]
发表于 2014-06-20 11:42 |只看该作者
回复 6# kerryxi


   
1. 在fork进程后,old page的anon_vma链表应该是parent vma和child vma的两个vma引用。这个应该没理解错吧?


old page的anon_vma链表 --》 aono_vma不是用链表,是用区间树。理解没错


2. 子进程在对应其中一个page写操作后,触发page cow,old page(parent的页面)的mapcount的引用计数会减一,但是old page的反向映射链表仍然是parent vma和child vma的两个vma引用。没看到do_wp_page有去除child vma的操作,对吗? 如果是的话,old_page的anon_vma链表中child vma节点什么时候去除呢?


对的,因为你光COW一页或几页,child_vma中没有COW的那些不还是共享父进程的页面。child vma什么时候去除,好像不会去除吧?因为内核并不知到什么时候child_vma中的页会全部COW出去吧。应该是到子进程退出的时候去除,^_^。。。。

论坛徽章:
0
8 [报告]
发表于 2014-06-20 11:44 |只看该作者
回复 7# njuzhyf

应该是到子进程退出的时候去除,^_^。。。。


额。。是vma消失的时候(进程退出,munmap等等)
   

论坛徽章:
0
9 [报告]
发表于 2014-06-20 13:07 |只看该作者
回复 8# njuzhyf


    明白了,多谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP