vmalloc和kmalloc有什么区别?
我到处搜索,发现大多数人都提倡使用" 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.) — kaiwan
对于系统调用,我们无需将GFP_ATOMIC传递给kmalloc(),可以使用GFP_KERNEL。我们不是中断处理程序:应用程序代码通过陷阱进入内核上下文,它不是中断。