vmalloc和kmalloc之间有什么区别?

vmalloc和kmalloc之间有什么区别?,c,linux-kernel,kmalloc,vmalloc,C,Linux Kernel,Kmalloc,Vmalloc,我在谷歌上搜索了一下,发现大多数人都提倡使用kmalloc,因为你可以保证获得连续的物理内存块。但是,如果找不到所需的连续物理块,那么kmalloc似乎也会失败。 拥有一个连续的内存块有什么好处?具体来说,为什么在系统调用中需要一个连续的物理内存块?有什么原因我不能直接使用vmalloc? 最后,如果我要在处理系统调用期间分配内存,我应该指定GFP_ATOMIC?系统调用是否在原子上下文中执行 GFP\u原子 分配是高优先级的,并且 他不睡觉。这是我们的旗帜 在中断处理程序中使用,底部 半途而废

我在谷歌上搜索了一下,发现大多数人都提倡使用
kmalloc
,因为你可以保证获得连续的物理内存块。但是,如果找不到所需的连续物理块,那么
kmalloc
似乎也会失败。
拥有一个连续的内存块有什么好处?具体来说,为什么在系统调用中需要一个连续的物理内存块?有什么原因我不能直接使用
vmalloc

最后,如果我要在处理系统调用期间分配内存,我应该指定
GFP_ATOMIC
?系统调用是否在原子上下文中执行

GFP\u原子

分配是高优先级的,并且 他不睡觉。这是我们的旗帜 在中断处理程序中使用,底部 半途而废和其他情况下 睡不着

GFP\u内核
这是正常分配,可能会阻塞。这是要使用的标志 安全睡眠时的进程内上下文代码

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

vmalloc
上的谷歌“我感到很幸运”中:

kmalloc是首选方式,只要您不需要很大的面积。问题是,如果您想从/到某些硬件设备进行DMA,则需要使用kmalloc,并且可能需要更大的数据块。解决的办法是尽快分配内存 内存变得支离破碎。简短回答:下载并阅读有关内存管理的章节

说真的,有很多与内核内存管理相关的微妙问题需要理解——我花了很多时间调试内核内存管理的问题


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

如果缓冲区将由物理寻址总线(如PCI)上的DMA设备访问,您只需要担心使用物理连续内存。问题是,许多系统调用无法知道它们的缓冲区最终是否会被传递到DMA设备:一旦将缓冲区传递到另一个内核子系统,您就真的不知道它将去哪里。即使内核现在不使用DMA缓冲区,未来的开发也可能会这样做

vmalloc通常比kmalloc慢,因为它可能必须将缓冲区空间重新映射到一个几乎连续的范围。kmalloc从不重新映射,尽管如果不使用GFP_调用,kmalloc可以阻止

kmalloc提供的缓冲区大小有限:128 KB*)。如果您需要一个非常大的缓冲区,您必须使用vmalloc或其他一些机制,比如在引导时保留高内存

*)早期的内核也是如此。在最近的内核上(我在2.6.33.2上进行了测试),单个kmalloc的最大大小高达4MB!(我写了一封信。)-凯万


对于不需要将GFP_原子传递给kmalloc()的系统调用,可以使用GFP_内核。您不是中断处理程序:应用程序代码通过陷阱进入内核上下文,它不是中断。

其他区别之一是kmalloc将返回逻辑地址(否则指定GPF_HIGHMEM)。逻辑地址放在“低内存”(物理内存的第一个千兆字节)中,并直接映射到物理地址(使用u_pa宏对其进行转换)。此属性意味着K分配的内存是连续内存


另一方面,Vmalloc能够从“高内存”返回虚拟地址。这些地址不能直接转换为物理地址(必须使用virt_to_page函数)。

Robert Love的Linux内核开发(第三版第12章,第244页)非常清楚地回答了这一问题

是的,在许多情况下不需要物理上连续的内存。在内核中使用kmalloc比使用vmalloc更多的主要原因是性能。这本书解释说,当使用vmalloc分配大内存块时,内核必须将物理上不连续的块(页)映射到单个连续的虚拟内存区域。由于内存实际上是连续的,并且物理上是非连续的,因此必须向页表中添加几个虚拟到物理地址映射。在最坏的情况下,将有(缓冲区大小/页面大小)个映射添加到页面表中

这也增加了访问此缓冲区时TLB(存储最近虚拟到物理地址映射的缓存项)的压力。这可能导致。

kmalloc()&
vmalloc()
函数是一个简单的接口,用于以字节大小的块获取内核内存

  • kmalloc()
    函数保证页面在物理上是连续的(并且实际上是连续的)

  • vmalloc()
    函数的工作方式与
    kmalloc()
    类似,只是它分配的内存实际上是连续的,不一定是物理连续的


  • 在32位系统上,kmalloc()返回内核逻辑地址(虽然是虚拟地址),该地址直接映射到物理地址(实际上是常数偏移量)。 这种直接映射确保我们获得一个连续的RAM物理块。适用于DMA,在DMA中,我们只给出初始指针,并期望随后为我们的操作提供连续的物理映射

    vmalloc()返回内核虚拟地址,而内核虚拟地址在物理RAM上可能没有连续映射。 适用于大内存分配和