免费注册 查看新帖 |

Chinaunix

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

[内核入门] VMA合并函数,vma_merge [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-02-27 13:53 |只看该作者 |倒序浏览
本帖最后由 darling54454 于 2016-02-27 13:54 编辑

先贴该函数主要代码:
struct vm_area_struct *vma_merge(struct mm_struct *mm, struct vm_area_struct *prev, unsigned long addr, unsigned long end, unsigned long vm_flags, struct anon_vma *anon_vma, struct file *file, pgoff_t pgoff, struct mempolicy *policy)
{
        pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
        struct vm_area_struct *area, *next;


        if (vm_flags & VM_SPECIAL)
                return NULL;

        if (prev)
                next = prev->vm_next;
        else
                next = mm->mmap;
        area = next;
       //传递进来的参数,next->vm_end == end,这个条件怎么会成立呢。
       // addr 和 end ,应该都是通过申请得到的区间吧,不应该和其他VMA覆盖的。
        if (next && next->vm_end == end)                /* cases 6, 7, 8 */
                next = next->vm_next;

       //同前一个合并。
        if (prev && prev->vm_end == addr && mpol_equal(vma_policy(prev), policy) && can_vma_merge_after(prev, vm_flags,anon_vma, file, pgoff)) {

        }

       //同后一个合并。
        if (next && end == next->vm_start && mpol_equal(policy, vma_policy(next)) && can_vma_merge_before(next, vm_flags, anon_vma, file, pgoff+pglen)) {

        }

        return NULL;
}

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
2 [报告]
发表于 2016-02-27 16:00 |只看该作者
addr 和 end 是通过申请获得,它可以和其他虚拟区重合,你可以做一下这方面的测试.

对于 "if (next && next->vm_end == end)                /* cases 6, 7, 8 */"

对于上面的 case 分别为:
case6:
新申请的 addr 为 prev->vm_end
新申请的 end   为 next->vm_end
但 next->vm_end == next->vm_next->vm_start;
case 7:
新申请的 addr 为 prev->vm_end
新申请的 end   为 next->vm_end
但 next->vm_end != next->vm_next->vm_start;
case 8:
新申请的 addr  > prev->vm_end
新申请的 end   为 next->vm_end
但 next->vm_end == next->vm_next->vm_start;

论坛徽章:
0
3 [报告]
发表于 2016-02-28 14:58 |只看该作者
回复 2# Buddy_Zhang1
你好。
如果说可以重叠话,那也挺困惑的。
假设addr = prev->end.
     end  是在next的区间内部的(next-> start < end < next->end).

那么程序的执行就是:
struct vm_area_struct *vma_merge(............)
{
        pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
        struct vm_area_struct *area, *next;

        if (vm_flags & VM_SPECIAL)
                return NULL;

        if (prev)
                next = prev->vm_next;
        else
                next = mm->mmap;
        area = next;
        if (next && next->vm_end == end)                /* cases 6, 7, 8 */
                next = next->vm_next;

        if (prev && prev->vm_end == addr && mpol_equal(vma_policy(prev), policy) && can_vma_merge_after(prev, vm_flags, anon_vma, file, pgoff)) {

                if (next && end == next->vm_start &&mpol_equal(policy, vma_policy(next)) &&can_vma_merge_before(next, vm_flags, anon_vma, file, pgoff+pglen) && is_mergeable_anon_vma(prev->anon_vma, next->anon_vma)) {
                                                        /* cases 1, 6 */
                        vma_adjust(prev, prev->vm_start, next->vm_end, prev->vm_pgoff, NULL);
                } else                                        /* cases 2, 5, 7 */
                        vma_adjust(prev, prev->vm_start, end, prev->vm_pgoff, NULL);
                return prev;
        }
        ....
        ....

        return NULL;
}
程序中对A和要新添加的区域进行了调用can_vma_merge_after来判断属性是不是可以合并,假设可以合并。
在vma_adjust会对B区域进行分割。但是,并没有对新添加的区域和B进行判断属性。
可以允许这样的操作?

   

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
4 [报告]
发表于 2016-02-28 16:30 |只看该作者
回复 3# darling54454

如果新的区和 next 区域重叠,那么就将 next 区 vma_split() 成两个区,next 区的前半部 merge 到新区内,next 区后半部区称为一个独立的新区.

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP