对unmap_vm_area的疑问
时间:2011-01-19
来源:互联网
我看ulk349页里,unmap_area_xxx依次在循环中执行map_area_xxx的反操作,但是在map_area_xxx中都有xxx_alloc,为什么在unmap_area_xxx中没有把相关的free了呢?
在350页写了一段话:....内核修改主内核页全局目录和它的子页表中的响应项,但是映射第4个GB的进程页表的项保持不变,这是在情理之中的,因为内核永远也不会收回扎根于主内核页全局目录中的页上级目录、页中级目录和页表。
这段话是什么意思?
以下代码摘自2.6.10,供参考
复制代码
复制代码
在350页写了一段话:....内核修改主内核页全局目录和它的子页表中的响应项,但是映射第4个GB的进程页表的项保持不变,这是在情理之中的,因为内核永远也不会收回扎根于主内核页全局目录中的页上级目录、页中级目录和页表。
这段话是什么意思?
以下代码摘自2.6.10,供参考
- int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
- {
- unsigned long address = (unsigned long) area->addr;
- unsigned long end = address + (area->size-PAGE_SIZE);
- pgd_t *dir;
- int err = 0;
-
- dir = pgd_offset_k(address);
- spin_lock(&init_mm.page_table_lock);
- do {
- pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
- if (!pmd) {
- err = -ENOMEM;
- break;
- }
- if (map_area_pmd(pmd, address, end - address, prot, pages)) {
- err = -ENOMEM;
- break;
- }
-
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
-
- spin_unlock(&init_mm.page_table_lock);
- flush_cache_vmap((unsigned long) area->addr, end);
- return err;
- }
- void unmap_vm_area(struct vm_struct *area)
- {
- unsigned long address = (unsigned long) area->addr;
- unsigned long end = (address + area->size);
- pgd_t *dir;
-
- dir = pgd_offset_k(address);
- flush_cache_vunmap(address, end);
- do {
- unmap_area_pmd(dir, address, end - address);
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- flush_tlb_kernel_range((unsigned long) area->addr, end);
- }
作者: amarant 发布时间: 2011-01-19
pXd_alloc,并不一定会分配内存,只是在对应address上的这一级页目录不存在的情况下,才会分配内存。如:
复制代码
这个函数实际上是确保对应位置上的这一级页目录存在。
关于这个地方的逻辑,我的理解是:
1、初始情况下,VM区域没有大于等于二级的页目录,VM区域一级页目录里面的值都是empty;
2、vmalloc的时候,需要确保各级的页目录存在,所以要调用pXd_alloc,并把每一级页目录都建立起来。这个时候一级页目录的相应位置从empty变成有值,然后这时建立起来的各级页目录都关联到init_mm里面去;
这里有个问题,内核没有自己的页表,它是借用了进程的页表,并且要求每个进程的页表在内核空间的范围内都是一样的。
而vmalloc的内存是在内核里面使用的,但是vmalloc这一下,只修改了当前生效的那个页表,其他进程的页表并没有一一去修改(lazy)。也就是说,你vmalloc之后,过了一段时间,发生了调度,页表被换了,然后你再去使用之前vmalloc出来的内存,可能对应的页表项是不存在的(当前的第一级页目录在对应区域的值还是empty)。
为了解决这个问题,缺页异常里面有个逻辑,就是从init_mm里面取值,在当前生效的页表中把这些缺少的这些页目录信息都补上。(其实就是把一级页目录里面的值跟init_mm做一个同步。大于等于二级的页目录都是直接引用init_mm里面的,并没有自己新建一份。)
然后,vfree的时候会发生什么呢?映射被取消,最后一级页目录里面的pte被修改。这个修改同样是在当前生效的页表里面去做的,那么其他进程的页表如何去同步呢?vmalloc的时候,页表项从无到有,可以由缺页异常来通知你该同步了;而现在页表项本身是存在的,缺页异常并不会发生。
呵呵,不过这时候根本就不需要同步,因为在每个进程的页表里面,VM区域的二级页目录都是直接引用的init_mm里面的,都是同一份。并且vfree的时候并不会释放任何页目录,只会修改最底层的pte。这样的修改是直接在所有进程的页表中同时生效的。
那么,如果vfree会释放页目录,会发生什么问题呢?页目录释放了,一级页目录里面对应的值被重置为empty。但是现在只重置了当前生效的页表,其他进程的页表没重置。什么时候同步呢?没法同步,因为其他进程的一级页目录里面对应的entry是有值的,不会触发缺页异常。并且这些entry指向的二级页目录已经被释放了,这不就BUG了么?
所以,vmalloc建立的页目录,一旦建立,就不会释放了。
- #define pmd_alloc(mm, pud, address) \
- ((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
- NULL: pmd_offset(pud, address))
关于这个地方的逻辑,我的理解是:
1、初始情况下,VM区域没有大于等于二级的页目录,VM区域一级页目录里面的值都是empty;
2、vmalloc的时候,需要确保各级的页目录存在,所以要调用pXd_alloc,并把每一级页目录都建立起来。这个时候一级页目录的相应位置从empty变成有值,然后这时建立起来的各级页目录都关联到init_mm里面去;
这里有个问题,内核没有自己的页表,它是借用了进程的页表,并且要求每个进程的页表在内核空间的范围内都是一样的。
而vmalloc的内存是在内核里面使用的,但是vmalloc这一下,只修改了当前生效的那个页表,其他进程的页表并没有一一去修改(lazy)。也就是说,你vmalloc之后,过了一段时间,发生了调度,页表被换了,然后你再去使用之前vmalloc出来的内存,可能对应的页表项是不存在的(当前的第一级页目录在对应区域的值还是empty)。
为了解决这个问题,缺页异常里面有个逻辑,就是从init_mm里面取值,在当前生效的页表中把这些缺少的这些页目录信息都补上。(其实就是把一级页目录里面的值跟init_mm做一个同步。大于等于二级的页目录都是直接引用init_mm里面的,并没有自己新建一份。)
然后,vfree的时候会发生什么呢?映射被取消,最后一级页目录里面的pte被修改。这个修改同样是在当前生效的页表里面去做的,那么其他进程的页表如何去同步呢?vmalloc的时候,页表项从无到有,可以由缺页异常来通知你该同步了;而现在页表项本身是存在的,缺页异常并不会发生。
呵呵,不过这时候根本就不需要同步,因为在每个进程的页表里面,VM区域的二级页目录都是直接引用的init_mm里面的,都是同一份。并且vfree的时候并不会释放任何页目录,只会修改最底层的pte。这样的修改是直接在所有进程的页表中同时生效的。
那么,如果vfree会释放页目录,会发生什么问题呢?页目录释放了,一级页目录里面对应的值被重置为empty。但是现在只重置了当前生效的页表,其他进程的页表没重置。什么时候同步呢?没法同步,因为其他进程的一级页目录里面对应的entry是有值的,不会触发缺页异常。并且这些entry指向的二级页目录已经被释放了,这不就BUG了么?
所以,vmalloc建立的页目录,一旦建立,就不会释放了。
作者: kouu 发布时间: 2011-01-19
回复 kouu
非常感谢!明白了~
非常感谢!明白了~
作者: amarant 发布时间: 2011-01-19
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28