【问题标题】:Why is kmalloc() more efficient than vmalloc()?为什么 kmalloc() 比 vmalloc() 更高效?
【发布时间】:2017-04-14 22:09:59
【问题描述】:

我认为kmalloc()在内核中分配连续的物理页面是因为虚拟内存空间直接映射到物理内存空间,只需添加一个偏移量。

但是,我还是不明白为什么它比vmalloc() 更有效率。 它仍然需要通过页表(内核页表),对吧?因为当进程切换到内核时,MMU 没有被禁用。那么为什么Linux直接将内核虚拟空间映射到物理内存呢?有什么好处?

include/asm-x86/page_32.h,有:

#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))

为什么内核需要计算物理地址?无论如何,它必须使用虚拟地址来访问内存,对吧?我无法弄清楚为什么需要物理地址。

【问题讨论】:

    标签: linux memory memory-management linux-kernel page-tables


    【解决方案1】:

    您的查询:-

    • 为什么 Kmalloc 比 vmalloc() 更高效?

    kmalloc 分配物理上连续(也实际上是连续)的内存区域。物理到虚拟映射是一对一的。

    对于vmalloc(),为每一页分配一个MMU/PTE值;物理到虚拟的映射不是连续的。

    vmalloc 通常比 kmalloc 慢,因为它可能必须将缓冲区空间重新映射到几乎连续的范围内。 kmalloc 从不重新映射。

    • 为什么 Linux 直接将内核虚拟空间映射到物理内存?

    Linux 内核中有一个概念称为 DMA(直接内存访问),它需要连续的物理内存。所以当内核触发 DMA 操作时,我们需要指定物理上连续的内存。这就是我们需要直接内存映射的原因。

    • 为什么内核需要计算物理地址?无论如何,它必须使用虚拟地址来访问内存,对吧?

    对于这个问题的答案,您需要阅读虚拟内存和物理内存之间的差异。但简而言之,每个加载和存储操作都是在物理内存上执行的(你在 PC 上的 RAM)

    物理内存指向 RAM。

    虚拟内存指向硬盘的交换区。

    【讨论】:

    • 谢谢。对于最后一个,我认为虚拟内存是指给 MMU 的虚拟内存地址,而物理内存是指由 MMU 计算的物理内存地址。看来我误解了这些术语。
    • 但是从"include/asm-x86/page_32.h"中的代码看来,虚拟内存确实是给MMU的虚拟内存地址,而物理内存确实是物理内存地址由 MMU 计算?由于加载和存储指令使用虚拟地址作为操作数,为什么内核需要计算物理地址?无论如何,MMU 都会这样做。
    • @hebothu 看一两句话不能帮助你理解 Linux 中的内存管理。你必须通过mmu的概念。但简单来说,虚拟内存只是幻觉。用于获取和放置数据的实际内存是您的内存,称为物理内存。
    • 要理解虚拟内存,你可以举个简单的例子,比如邮递员,明信片上有一个地址,但邮递员不知道它是不是正确的地址。所以他首先到达你的状态。他试图匹配你的家庭住址。为了得到你的家庭住址,他需要人或 GPS 的帮助。一旦他得到您的家庭地址,他就会到达您的地址并交付您的数据包。你的家庭地址是物理内存,GPS或人是MMU,给你寄明信片的是cpu,明信片上的地址是虚拟地址,你的状态是硬盘(交换区)。希望你能理解。
    • 声明 virtual memory point to the swap area of​​ your HARD DISK 对于内核来说是错误的。虚拟内存通过页表映射到物理内存或通过用户空间中的故障(以及后备存储的无效页表)进行交换。所有内核内存都预先映射了kmalloc。对于vmalloc,必须进行额外的PTE(消耗一些内存),此外,TLB/page-hit/table walk 将在使用内存时应用。对于内核功能,通常需要知道物理地址,这变得更加困难。
    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    相关资源
    最近更新 更多