vmalloc和kmalloc有什么区别?

时间:2020-03-06 14:33:11  来源:igfitidea点击:

我到处搜索,发现大多数人都提倡使用" kmalloc",因为可以确保我们获得连续的物理内存块。但是,如果找不到所需的连续物理块,似乎kmalloc'也会失败。 拥有连续的内存块有什么好处?具体来说,为什么我需要在系统调用中有一个连续的物理内存块?有什么理由不能只使用vmalloc吗? 最后,如果要在处理系统调用期间分配内存,我应该指定GFP_ATOMIC`吗?系统调用是否在原子上下文中执行?

GFP_ATOMIC

  The allocation is high-priority and
  does not sleep. This is the flag to
  use in interrupt handlers, bottom
  halves and other situations where you
  cannot sleep.
  
  GFP_KERNEL
  This is a normal allocation and might block. This is the flag to use
  in process context code when it is safe to sleep.

解决方案

拥有连续的内存块有什么好处?具体来说,为什么我需要在系统调用中有一个连续的物理内存块?有什么原因我不能只使用vmalloc吗?

来自Google在vmalloc上的"我很幸运":

只要不需要很大的区域,kmalloc是首选方法。问题是,如果要在某些硬件设备之间进行DMA,则需要使用kmalloc,并且可能需要更大的块。解决方案是尽快分配内存,然后再
内存碎片化。

简短答案:下载Linux设备驱动程序,然后阅读有关内存管理的章节。

认真地说,我们需要了解许多与内核内存管理有关的细微问题,因为我花了很多时间来调试它。

vmalloc()很少使用,因为内核很少使用虚拟内存。 kmalloc()是通常使用的,但是我们必须知道不同标志的后果,并且需要一种策略来处理在失败时发生的情况,特别是如果我们像建议的那样在中断处理程序中。

如果缓冲区将由物理寻址总线(如PCI)上的DMA设备访问,则只需担心使用物理上连续的内存。问题在于,许多系统调用无法知道其缓冲区是否最终将传递给DMA设备:将缓冲区传递给另一个内核子系统后,我们实际上就无法知道它的去向。即使今天内核不使用DMA <I>缓冲区,将来的开发也可能会使用。

vmalloc通常比kmalloc慢,因为vmalloc必须将缓冲区空间重新映射到实际上连续的范围内。 kmalloc永远不会重新映射,尽管如果不使用GFP_ATOMIC调用,kmalloc可能会阻塞。

kmalloc可以提供的缓冲区大小受到限制:128 KB *。如果需要非常大的缓冲区,则必须使用vmalloc或者其他一些机制,例如在引导时保留大量内存。

*) This was true of earlier kernels. On recent kernels (I tested this on 2.6.33.2), max size of a single kmalloc is up to 4 MB! (I wrote a fairly detailed post on this.) &mdash; kaiwan

对于系统调用,我们无需将GFP_ATOMIC传递给kmalloc(),可以使用GFP_KERNEL。我们不是中断处理程序:应用程序代码通过陷阱进入内核上下文,它不是中断。