kmalloc,vmalloc,kmap 缺页的讨论
来源:互联网 发布:招聘程序员的工作要求 编辑:程序博客网 时间:2024/05/20 12:48
kmap 类似vmalloc ,但是他不会缺页。为什么?
(具体的流程就是fork或者execv时拷贝了内核主页表的pgd条目(可理解为指针)。至于具体的pgd条目,指向的都是共享的pmd,pte)
kmap在系统初始化时,就会一直分配到pte级,
所以后面fork或者execv出来的进程访问kmap空间都不缺页,
但vmalloc是会重新生成新的pgd条目 ,
所有后面的进程内核空间里没有这个地址空间,就会缺页。
那么如果有多个进程同时执行kmap_atomic会不会冲突呢?答案是不会。
因为虽然多个kmap_atomic流程都尝试去修改内核主页表,但是kmap_atomic
获取的虚拟地址是每个cpu互相不冲突的,因为虚拟地址不冲突,从而修改的主页表
的pte位置也不同,也就没有同步的必要。
每个进程被新生成的时候调用的是fork, fork先复制内核页表,再遍历父进程vma区间所在的页表,即用户态页表,然后复制一份。
于是就有两个时机可能复制内核页表:
fork时,以及execv时,前者调用链是do_fork->dup_mm->mm_init->mm_alloc_pgd->pgd_alloc
后者是do_execve->mm_alloc->mm_init->mm_alloc_pgd->pgd_alloc
那既然fork能拷贝内核页表,为什么还要exec里再拷贝一遍?
其实,如果父进程是内核线程,那么fork并没有必要拷贝一份内核页表,它直接用共享的那个主页表就行了,即切换到内核线程时,直接把页表基地址设置
成内核主页表就行了。所以dup_mm会判断如果current->mm为空的话,就没有必要调用mm_init了。
那如果新生成的内核线程突然想执行一个用户态程序,就会调用execv, 这个时候,就需要给用户态程序拷贝一下内核页表了。
两者最终调用的都是pgd_alloc
根据内核态下界地址0xc000 0000计算出pdg中的index,这之上的index都是内核态pdg
boundary = pgd_index(__PAGE_OFFSET);
清空用户态映射
memset(pgd, 0, boundary * sizeof(pgd_t));
拷贝内核态页表pgd指针
memcpy(pgd + boundary,
init_level4_pgt + boundary,
(PTRS_PER_PGD - boundary) * sizeof(pgd_t));
(具体的流程就是fork或者execv时拷贝了内核主页表的pgd条目(可理解为指针)。至于具体的pgd条目,指向的都是共享的pmd,pte)
kmap在系统初始化时,就会一直分配到pte级,
所以后面fork或者execv出来的进程访问kmap空间都不缺页,
但vmalloc是会重新生成新的pgd条目 ,
所有后面的进程内核空间里没有这个地址空间,就会缺页。
那么如果有多个进程同时执行kmap_atomic会不会冲突呢?答案是不会。
因为虽然多个kmap_atomic流程都尝试去修改内核主页表,但是kmap_atomic
获取的虚拟地址是每个cpu互相不冲突的,因为虚拟地址不冲突,从而修改的主页表
的pte位置也不同,也就没有同步的必要。
每个进程被新生成的时候调用的是fork, fork先复制内核页表,再遍历父进程vma区间所在的页表,即用户态页表,然后复制一份。
于是就有两个时机可能复制内核页表:
fork时,以及execv时,前者调用链是do_fork->dup_mm->mm_init->mm_alloc_pgd->pgd_alloc
后者是do_execve->mm_alloc->mm_init->mm_alloc_pgd->pgd_alloc
那既然fork能拷贝内核页表,为什么还要exec里再拷贝一遍?
其实,如果父进程是内核线程,那么fork并没有必要拷贝一份内核页表,它直接用共享的那个主页表就行了,即切换到内核线程时,直接把页表基地址设置
成内核主页表就行了。所以dup_mm会判断如果current->mm为空的话,就没有必要调用mm_init了。
那如果新生成的内核线程突然想执行一个用户态程序,就会调用execv, 这个时候,就需要给用户态程序拷贝一下内核页表了。
两者最终调用的都是pgd_alloc
根据内核态下界地址0xc000 0000计算出pdg中的index,这之上的index都是内核态pdg
boundary = pgd_index(__PAGE_OFFSET);
清空用户态映射
memset(pgd, 0, boundary * sizeof(pgd_t));
拷贝内核态页表pgd指针
memcpy(pgd + boundary,
init_level4_pgt + boundary,
(PTRS_PER_PGD - boundary) * sizeof(pgd_t));
- kmalloc,vmalloc,kmap 缺页的讨论
- kmalloc、vmalloc、kmap、malloc的区别
- 关于kmalloc、vmalloc及kmap
- 关于kmalloc、vmalloc及kmap
- 关于kmalloc、vmalloc及kmap
- 关于kmalloc、vmalloc及kmap
- kmap/kmalloc/ioremap/kmalloc/kzalloc/kcalloc/vmalloc
- kmap/kmalloc/ioremap/kmalloc/kzalloc/kcalloc/vmalloc
- Vmalloc与kmalloc的区别
- kmalloc、vmalloc、malloc的区别
- malloc kmalloc vmalloc的区别
- vmalloc 和 kmalloc 的详解
- kmalloc、vmalloc、malloc的区别
- kmalloc、vmalloc、malloc的区别
- kmalloc、vmalloc、malloc的区别
- kmalloc、vmalloc、malloc的区别
- Kmalloc和Vmalloc的区别
- kmalloc、vmalloc、malloc的区别
- OpenSceneGraph 概览
- 图像处理几何运算2--栅条,中间扩展显示图像
- Windows Mobile中的Web Service应用
- Qt贪吃蛇(代码裸写,不用creator)
- 通过java反射调用远程方法
- kmalloc,vmalloc,kmap 缺页的讨论
- linux下socket编程实例
- Phonegap + HTML5 开发经验小结
- 数字取整
- php之大话装饰模式
- 第七次上机实验
- 为Windows CE平台开发嵌入式系统
- 【某教授有感而发_送给各位技术人员】赞
- 算法基础