embeddedlwp 发表于 2011-09-04 17:15

分配线性地址区间问题

本帖最后由 embeddedlwp 于 2011-09-04 17:16 编辑

linux 2.6.11的内存管理部分,do_mmap_pgoff中有这么一段munmap_back:
        vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
        if (vma && vma->vm_start < addr + len) {
                if (do_munmap(mm, addr, len))
                        return -ENOMEM;
                goto munmap_back;
        }在ULK3 P371上的解释是find_vma_prepare()函数也检查是否还存在与新区间重叠的线性区。这种情况发生在函数返回一个非空的地址,这个地址指向一个线性区,而该区的起始地址位置位于新区间结束地址之前的时候。在这种情况下,do_mmap_pgoff()调用do_munmap()删除新的区间,然后重复整个步骤。

这里如果重复整个步骤,也就是重新执行find_vma_prepare,之前调用do_munmap释放了那个由get_unmmaped_area找到的空闲的地址空间,那个find_vma_prepare也没有分配地址空间的功能,那么程序怎么往下执行了啊?我感觉get_unmmaped_area找到的空闲地址空间一定是不与别的区间重叠的(否则返回NULL),这样这段code就不会执行了。

amarant 发表于 2011-09-05 08:15

沒看懂你說什麼。。
線性區不會有重複的

vma && vma->vm_start < addr + len
這個條件是檢測是不是傳入的地址與已存在的線性區重疊
如果是的話,先取消之前的映射再繼續

embeddedlwp 发表于 2011-09-05 09:33

回复 2# amarant


    呵呵,关键是如何继续,这里调用的do_munmap()已经把get_unmmaped_area()获得的线性地址区间取消掉了。没了线性区间怎么往下执行呢,求解惑!

amarant 发表于 2011-09-05 10:03

回复 3# embeddedlwp


    這個函數的作用就是為了分配線性區,如果所請求的線性區已經被映射了就先unmap,這樣才能實現函數的功能。。

embeddedlwp 发表于 2011-09-05 10:16

回复 4# amarant


    如果调用do_munmap()了,goto munmap_back;但是之后do_mmap()的操作中没有调用get_unmapped_area(),也就是这次释放这个线性区就不存在了,他也没有去获得新的线性区,函数也不会实现他的功能。

amarant 发表于 2011-09-05 10:41

记不清楚了,你自己好好看看吧 :em06:

embeddedlwp 发表于 2011-09-05 10:43

回复 6# amarant


    奥呵呵,多谢了,刚才在linuxform看到04年有人提过这个问题,也是最后没人解决。

allen303allen 发表于 2011-09-05 17:16

感觉楼主有几个认识上的误区:
1. get_unmmaped_area()是不会创建一个线性区间的。
它只返回一个地址addr,确保从addr开始,长度为len的区间是没有被映射的(多数情况下)。真正分配线性区间的操作是后面的kmem_cache_zalloc分配一个vma结构,然后设置vma的start和end及其他字段,并加入到vma链表和红黑树中。这样一个线性区间才创建完毕。

2. 所贴这段代码的作用。
这段代码的目的是检查以确保addr开始,长度为len的区间内没有其他的映射区间,如果有,就要把那些区间释放,直到通过find_vma_prepare找不到vma或者找到的vma不在addr开始,长度为len的范围内。
find_vma_prepare肯定没有分配地址空间的功能,它只是找到第一个结束地址大于addr的vma。
所以只要确认了上面说的问题,就可以跳过这段代码往下执行了(往下去分配线性区间了)。

3. get_unmmaped_area()返回的addr并不一定是ok的。
也就是说该函数返回的addr,并不一定从它开始,长度为len的区间内一定没有其他的映射,arch_get_unmapped_area()函数中的开始就有个判断,如果flags中标记了MAP_FIXED,就直接返回传入的addr,根本不去找别的了。
所以只要用户指定了MAP_FIXED标记,除了对该地址做页对齐,就直接在对齐后的地址的基础上做映射了,这就是楼主所贴代码存在的目的,在这种情况下,把该区间内其他的映射区间都删除(这个是有风险的,所以除非你很确信自己在做什么,否则不要随便用MAP_FIXED标记),来给一会要映射的区间让路。

embeddedlwp 发表于 2011-09-07 17:40

本帖最后由 embeddedlwp 于 2011-09-07 17:59 编辑

回复 8# allen303allen


    高手!醍醐灌顶!

wukui1008 发表于 2011-12-05 11:02

:dizzy:
找到这个贴不容易啊,
这个问题也困惑我一天了
我开始也是这么觉得
get_unmmaped_area找到的空闲地址空间一定是不与别的区间重叠的
接下来的步骤却又说要删除重叠区间
把我可搞晕了
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 分配线性地址区间问题