关于内核的内存分配 TLB刷新

yjzl1911 2010-05-21 04:20:23
最近在看《linux内核设计与实现》,在“内存管理”一章里看到这么一句话:
“通过vmalloc()获得的页必须一个一个地进行映射(因为他们物理上是不连续的),这就会导致比直接内存映射大得多的TLB抖动。”
感觉自己理解不是很透,希望大家能指教指教。
先说说我的理解:
当内核用kmalloc分配连续的物理内存时,内核页表不用变化,因为kmalloc分配到的是内核虚拟地址空间中的物理内存映射区域,而这部分区域的内存在kmalloc调用前就已经映射好了。 只是当内核真正去访问这些内存时,应该也可能会发生TLB的抖动。因为在访问申请到连续的物理内存时,MMU会用到内核的页表项进行虚拟地址到物理地址的转换,如果说当前所需的页表项不在TLB中时,就会换进新的PTE,换出旧的PTE.
而对于vmalloc申请的内存,在访问时由于要修改内核的页表项以使得物理上不连续的页在逻辑上连续起来,所以肯定会发生PTE的换进和换出,即肯定会发生TLB抖动。

所以 “这就会导致比直接内存映射大得多的TLB抖动”。

希望个位高手能不吝赐教~~
...全文
777 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
zaghost 2012-12-10
  • 打赏
  • 举报
回复
kmalloc不会增加新的页表项, vmalloc会增加新的页表项,所以就抖动了啦
最后一个菜鸟 2012-12-09
  • 打赏
  • 举报
回复
引用 25 楼 load2006 的回复:
这个问题我也困惑好久,开始我的疑问跟elfirex兄是一样的,后来看了射牛斗兄的说法觉得有些道理,自己又搜了些资料,进一步印证了射斗牛兄的观点; x86系列cpu的mmu中,一般有四种不同的tlb缓存: 第一组4k页面的指令缓存,instruction-tlb; 第二组4k页面的数据缓存,data-tlb 第三组2M/4M的指令tlb 第四组2M/4M的数据tl……
内核可将用于连续内存映射的pgd的一个属性,使每一页为4M。所以内核应该不会直接管理四组tlb缓存,而是根据改变页的大小,tlb根据不同页大小选择不同的tlb缓存吧
百科全书学派 2012-12-09
  • 打赏
  • 举报
回复
这个问题我也困惑好久,开始我的疑问跟elfirex兄是一样的,后来看了射牛斗兄的说法觉得有些道理,自己又搜了些资料,进一步印证了射斗牛兄的观点; x86系列cpu的mmu中,一般有四种不同的tlb缓存: 第一组4k页面的指令缓存,instruction-tlb; 第二组4k页面的数据缓存,data-tlb 第三组2M/4M的指令tlb 第四组2M/4M的数据tlb 大家可以搜索资料《Translation Look-aside Buffer(TLB)设计综述》 kmalloc申请的2M连续的物理内存,对于os内存中的页面表来说,肯定有2M/4k个页面表条目; 但是对于INTEL的tlb来说,只需要一个2M的tlb缓存条目(第四组中的一条记录)就可以表示; 而vmalloc申请的2M不连续物理内存,则需要2M/4K个tlb(第二组中的多条记录); 因此访问kmalloc的连续物理内存,其抖动更小(也就是说tlb miss较少) 有一点不明白的地方是,linux 内核是否显示管理了intel的四组tlb缓存? 例如tlb miss的是偶,tlb条目置换是由os来做的,还是intel的硬件来做的? 看过一些tlb的硬件资料,risc cpu的tlb miss一般以软件方式,即由os来做的,可以采用类似cache管理的最近最近未使用等算法;
iguest 2010-07-14
  • 打赏
  • 举报
回复
学习ing
linkejin 2010-07-07
  • 打赏
  • 举报
回复
不了解啊
zkuang82 2010-07-07
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 sheniudou 的回复:]
kmalloc也好,vmalloc也好,分配到的物理页都是4KB的页,但由于kmalloc分配到的页物理地址连续,所以1024个4KB页构成一个连续的4MB空间,从而可以被TLB当作一个“大页”来处理。

[/Quote]

1. 射牛兄的意思是说TLB在硬件上可以动态指定页面大小?恐怕不行吧?
2. 假设TLB可以在4K页面的内核里使用4M页面的方式做映射。内核计算页面起始位置时,还是以4K为边界。也就是说,硬件上判断TLB是否命中对比的是4M的边界跟4K的边界。也就是说,就算该4K的页面的确落入之前已经在TLB里的4M的页面,也可能会有4K整数倍的偏移,一样也会Miss才对吧?
豫让 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 elfirex 的回复:]

引用 19 楼 sheniudou 的回复:
kmalloc分配的内存是物理连续的,可以使用“大页”TLB表项,vmalloc分配的内存不能保证是物理连续的,只能使用“小页”TLB表项,抖动的几率当然会大。



对,sheniudou兄说的不错,但这还不是原因。系统在启动以后已经初始化MMU,页的大小也已经固定。也就是说,kmalloc也好,vmalloc也好其实已经在使用相同的页大……
[/Quote]

kmalloc也好,vmalloc也好,分配到的物理页都是4KB的页,但由于kmalloc分配到的页物理地址连续,所以1024个4KB页构成一个连续的4MB空间,从而可以被TLB当作一个“大页”来处理。
如果1个4MB“大页”TLB表项映射到的物理地址为physical_addr,设任意映射到该TLB表项的虚拟地址为virtual_addr,则其对应的物理地址是physical_addr + (virtual_addr & (4M-1))。
zkuang82 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 sheniudou 的回复:]
kmalloc分配的内存是物理连续的,可以使用“大页”TLB表项,vmalloc分配的内存不能保证是物理连续的,只能使用“小页”TLB表项,抖动的几率当然会大。

[/Quote]

对,sheniudou兄说的不错,但这还不是原因。系统在启动以后已经初始化MMU,页的大小也已经固定。也就是说,kmalloc也好,vmalloc也好其实已经在使用相同的页大小。内核本身是以页为单位来分配内存的。也就是无论页面连续与否,访问内存也是以页为边界的。这不存在说vmalloc的页必须是小页,只要系统设定MMU使用大页,那vmalloc也在使用大页。也就是说kmalloc跟vmalloc在申请相同大小的内存以后,其实页面的数量是相同的。只要程序对内存的访问模式一直(也就是说出于同一个程序),那么TLB切换频率应该不会有太大的差别吧?
豫让 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 elfirex 的回复:]

引用 17 楼 sheniudou 的回复:
不好意思,可能我没说清楚,我并没说改变页的大小,这里的“大页”和“小页”是从TLB角度来看的,从TLB的角度来看一个“大页”表项代表4MB空间,但这4MB空间是由1024个物理连续的4KB页构成的。“小页”和“大页”TLB在同一CPU上存在。


如果这是从TLB角度去看的话,那kmalloc跟vmalloc所产生的抖动机率也不会有明显差别吧……
[/Quote]

kmalloc分配的内存是物理连续的,可以使用“大页”TLB表项,vmalloc分配的内存不能保证是物理连续的,只能使用“小页”TLB表项,抖动的几率当然会大。

系统只有一种页大小,对于一个“大页”表项,当TLB miss时,只需对4MB空间的第一个4KB页进行地址转换,把物理地址填入TLB表项即可,4MB空间内的任意虚拟地址对应的物理地址都可以根据第一个页的物理地址计算出来(1024个物理页地址是连续的)。
zkuang82 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 sheniudou 的回复:]
不好意思,可能我没说清楚,我并没说改变页的大小,这里的“大页”和“小页”是从TLB角度来看的,从TLB的角度来看一个“大页”表项代表4MB空间,但这4MB空间是由1024个物理连续的4KB页构成的。“小页”和“大页”TLB在同一CPU上存在。
[/Quote]

如果这是从TLB角度去看的话,那kmalloc跟vmalloc所产生的抖动机率也不会有明显差别吧?况且,MMU可以同时工作在大页跟小页两种状态?这里的问题在于kmalloc和vmalloc的区别,并不是页面大小的区别。
豫让 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 elfirex 的回复:]

引用 15 楼 sheniudou 的回复:

如果采用4MB表项, 那么只会在第一次访问该模块时miss一次;如果采用4KB表项,完整表示该模块空间需要1024个小页表项,而TLB只有512个小页表项,也就是说TLB无法cache该模块的所有地址映射(而4MB表项是可以的)。如果addr1和addr2分别属于不同的页(4KB),并且映射到同一个TLB表项,那么先访问addr1导致1次mis……
[/Quote]

不好意思,可能我没说清楚,我并没说改变页的大小,这里的“大页”和“小页”是从TLB角度来看的,从TLB的角度来看一个“大页”表项代表4MB空间,但这4MB空间是由1024个物理连续的4KB页构成的。“小页”和“大页”TLB在同一CPU上存在。
zkuang82 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 sheniudou 的回复:]

如果采用4MB表项, 那么只会在第一次访问该模块时miss一次;如果采用4KB表项,完整表示该模块空间需要1024个小页表项,而TLB只有512个小页表项,也就是说TLB无法cache该模块的所有地址映射(而4MB表项是可以的)。如果addr1和addr2分别属于不同的页(4KB),并且映射到同一个TLB表项,那么先访问addr1导致1次miss,接着访问addr2又是一次miss。…
[/Quote]

sheniudou兄,你的意思我明白。我的问题是,这不是vmalloc跟kmalloc的区别所在,因为他们采用的是相同的页面映射方式。改变页面大小当然可以改变TLB的抖动状况,但vmalloc跟kmalloc应该不会对TLB产生太大的区别,除非CPU本身有基于地址相关性的预加载。
豫让 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 elfirex 的回复:]

引用 12 楼 sheniudou 的回复:

引用 11 楼 elfirex 的回复:

一点疑问。
TLB保存最近发生访问的页面translate出来的地址,那么应该是时间相关的。跟物理上是否连续应该没有直接关系。所以,只要你一直在访问那些页面,应该不会出现太多抖动。
如果跟地址的连续性有关,那应该是某些架构的芯片做了基于地址连续性的预加载吧?


举个例子:
如果一个内……
[/Quote]

如果采用4MB表项, 那么只会在第一次访问该模块时miss一次;如果采用4KB表项,完整表示该模块空间需要1024个小页表项,而TLB只有512个小页表项,也就是说TLB无法cache该模块的所有地址映射(而4MB表项是可以的)。如果addr1和addr2分别属于不同的页(4KB),并且映射到同一个TLB表项,那么先访问addr1导致1次miss,接着访问addr2又是一次miss。
zkuang82 2010-07-05
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 sheniudou 的回复:]

引用 11 楼 elfirex 的回复:

一点疑问。
TLB保存最近发生访问的页面translate出来的地址,那么应该是时间相关的。跟物理上是否连续应该没有直接关系。所以,只要你一直在访问那些页面,应该不会出现太多抖动。
如果跟地址的连续性有关,那应该是某些架构的芯片做了基于地址连续性的预加载吧?


举个例子:
如果一个内核模块需要4MB空间,如果分配的4MB空间是物理地址……
[/Quote]

这里的问题是linux并不会动态更改页表的映射方式,就是说如果你用的是4MB的映射,那么你就一直用它,如果你用的是4KB的映射,那你也不能该成4mb,反之亦然。TLB本身只存储从页表得到的翻译结果,所以大页跟小页在这里应该不是引起vmalloc跟kmalloc对TLB抖动差异的理由才对。
yangzhifu 2010-07-05
  • 打赏
  • 举报
回复
[Quote=引用楼主 yjzl1911 的回复:]
最近在看《linux内核设计与实现》,在“内存管理”一章里看到这么一句话:
“通过vmalloc()获得的页必须一个一个地进行映射(因为他们物理上是不连续的),这就会导致比直接内存映射大得多的TLB抖动。”
感觉自己理解不是很透,希望大家能指教指教。
先说说我的理解:
当内核用kmalloc分配连续的物理内存时,内核页表不用变化,因为kmalloc分配到的是内核虚拟地址空间中的物理……
[/Quote]

站在我理解的角度,你已经理解的比较清楚了
豫让 2010-07-04
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 elfirex 的回复:]

一点疑问。
TLB保存最近发生访问的页面translate出来的地址,那么应该是时间相关的。跟物理上是否连续应该没有直接关系。所以,只要你一直在访问那些页面,应该不会出现太多抖动。
如果跟地址的连续性有关,那应该是某些架构的芯片做了基于地址连续性的预加载吧?
[/Quote]

举个例子:
如果一个内核模块需要4MB空间,如果分配的4MB空间是物理地址连续的,那么可以使用“大页”TLB表项,如果一个“大页”TLB表项可以表示4MB空间的话, 则只需要1个“大页”表项。

反之,如果物理地址不连续, 则只能使用4KB“小页”表项,那么总共需要1024个表项来完整表示这4MB空间,如果CPU“小页”TLB只有512个表项的话...
zkuang82 2010-07-02
  • 打赏
  • 举报
回复
一点疑问。
TLB保存最近发生访问的页面translate出来的地址,那么应该是时间相关的。跟物理上是否连续应该没有直接关系。所以,只要你一直在访问那些页面,应该不会出现太多抖动。
如果跟地址的连续性有关,那应该是某些架构的芯片做了基于地址连续性的预加载吧?
hallowwar 2010-06-29
  • 打赏
  • 举报
回复
深奥的东西,段页我是不清楚的,围观
karlzheng 2010-06-29
  • 打赏
  • 举报
回复
找相关资料学习了一下,感觉:
vmalloc分配的是不连续的空间,kmalloc分配的是连续的空间,所以vmalloc要查找的页表次数会多,抖动也会多...
豫让 2010-06-29
  • 打赏
  • 举报
回复
修改页表项会导致额外开销,但并不是加大TLB抖动的原因。

TLB分两种,一种的一个表项仅能表示4KB空间(所谓”小页“),另一种的一个表项能表示2MB,4MB乃至更多空间(所谓”大页“————由连续的物理页构成)。

vmalloc分配的内存由于物理地址不连续只能使用”小页“的TLB项,所以会导致更大的TLB抖动。
加载更多回复(6)

4,438

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧