您好、欢迎来到现金彩票网!
当前位置:一品彩票app下载 > 共享页表 >

32位arm linux为什么内核在fork进程的时候要复制(memcpy)内核PGD

发布时间:2019-05-11 15:38 来源:未知 编辑:admin

  32位arm linux,为什么内核在fork进程的时候要复制(memcpy)内核PGD init页表(swapper_pg_dir)?

  以下讨论仅适用于32位使用两级页表的arm linux,kernel 版本为3.9. kernel在fork进程的时候会复制内核的PGD页表(3G-4G部分),问题是为什么要做这个memcpy的动作? 这样做岂不是和“所有用户进程共享内核页表” 这个结论矛盾了? 而且还有一个问题是一旦有一个进程更新了内核页表,那么是不是所有其它的进程都需要同步这个修改?那么对于有成千上百个进程的情况,这岂不是个灾难? source code: (--表示函数调用) do_fork -- co…

  题主的理解不完全正确,这样做岂不是和“所有用户进程共享内核页表” 这个结论矛盾了?这个解读是错误的。

  正确的解读是:所有的进程内核态空间的映射关系是完全一样的,但每个进程的页表是独立一份(也即每个进程中关于内核态空间的页表内容是完全一样的)。

  所以题主是有两个问题需要回答的,我来写一下吧:1. 为什么内核空间页表各进程内容是完全一样,还是每个进程独立一份2. 为什么fork进程,需要从swapper_pg_dir拷贝一份

  问题1:为什么内核空间页表各进程内容是完全一样,还需要每个进程独立一份我认为是出于性考虑,如果所有进程在内核态都使用同一份页表,CPU从用户态进入内核态的所有场景(系统调用,硬中断),首先做的一个事情就是切页表,然后得刷TLB等事情,开销较大,不可接受,所以采用每个进程进入内核态进不需要切换页表的方案。

  题2:为什么fork进程,需要从swapper_pg_dir拷贝一份答案同样是很简单,内核态空间只有lowmem的映射是稳的(永远不会变),对于lowmem之后的虚拟地址空间的映射是时刻在发生变的,比如vmalloc操作,ioremap操作,kmap等等操作。由于所有进程的内核映射关系都应的数据完全一致的,那一旦要修改,则面临两个问题:

  1) 如何让所有进程感知,并修改页表2)在此之后fork出来的进程,怎么感知这个映射

  对于1),如果马上修改所有进程页表,会引发系统“群惊”,而对2)总得找个地方把最新的页表记录下来,在fork进程时拷贝一份来使用。

  是的,Linux内核使用swapper_pg_dir作为主控页表,所以内核空间的页表修改,都只修改这个页责,不信你可以看看vmalloc函数,kmap函数是修改哪个页表的。

  由于其它进程内核态页表是没有变化的,所以访问最新的内核指针时,会出现 缺页异常,这时内核会将swapper_pg_dir相应的页表项拷贝到当前进程,接着运行。

   你好,我想问下主内核页表就是init进程的页表么?因为看到很多都是这样说,可是创建子进程时候复制的是swapper_pg_dir。就是说swapper_pg_dir有属于哪个进程么,还是说就是一个内核页表蓝本,创建进程都需要复制相应项,和init进程并没有什么直接关系? 因为才开始学习有点表述不清(T_T)

  我们先将内核的启动过程,以及产生init进程(精灵进程、1号进程)的过程列举如下(下面只说arm架构,x86也是类似的):

  1)swapper_pg_dir 是0号进程使用的页表,0号进程又称为idle进程,它的名字为swapper。该进程的task和mm分别是init_task和init_mm这两个变量。2)后续所有进程(包含init进程),fork时产生时这页表都是从0号进程里面拷贝出出去的

  还是以ARM架构为例子(可能与架构是无关的),在内核空间除了lowmem之外的内存空间,有vmalloc区,kmap区,这些区都是以4K为单位分配的虚拟空间。

  ARM架构上的这些空间对应的页表,一定是二级页表(这点要切点)。而 fork进程时,内核空间的页表是从swapper_pg_dir 页表拷贝的,但请注意,这个拷贝只拷贝了一级页表,二级页是共享的(这个关键技术,我之前一直没有点出这个关键点,说声sorry)。

http://styleinch.com/gongxiangyebiao/184.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有