GFP_KERNEL 对比 GFP_DMA 和 kmalloc() 对比 dma_alloc_coherent()
GFP_KERNEL vs GFP_DMA and kmalloc() vs dma_alloc_coherent()
我总是使用 dma_alloc_coherent() 来分配带有标志 GFP_KERNEL 的 DMA 缓冲区并且到目前为止没有观察到问题,我的理解是这两个标志都允许调用者休眠..
所以我很好奇 GFP_DMA 选项在这种情况下是否真的有用?该标志也可用于 kmalloc(),但是我们不应该使用 kmalloc() 来分配 DMA 缓冲区而只能使用 dma api 吗?
经过一些研究,我发现 LLD 第 3 版第 8 章中的以下陈述:
每当分配新页面以满足内存分配请求时,内核都会构建可用于搜索的区域列表。如果指定了 _ _GFP_DMA,则只搜索 DMA 区域:如果低地址没有内存可用,则分配失败。如果没有特殊标志,则搜索普通内存和 DMA 内存。
所以看起来标志 GFP_DMA 是 GFP_KERNEL 的子集。
dma_alloc_coherent() returns 已设置适当内存属性的地址范围,因此可以自然处理缓存效果。我们不需要对这些地址做任何缓存操作。
如果我们使用 kmalloc() 分配的地址进行 DMA 操作,那么我们需要根据传输方向执行额外的缓存操作,如缓存清理和缓存无效。
GFP_DMA 标志只是从 32 位机器上的 DMA 区域分配内存。
我总是使用 dma_alloc_coherent() 来分配带有标志 GFP_KERNEL 的 DMA 缓冲区并且到目前为止没有观察到问题,我的理解是这两个标志都允许调用者休眠..
所以我很好奇 GFP_DMA 选项在这种情况下是否真的有用?该标志也可用于 kmalloc(),但是我们不应该使用 kmalloc() 来分配 DMA 缓冲区而只能使用 dma api 吗?
经过一些研究,我发现 LLD 第 3 版第 8 章中的以下陈述:
每当分配新页面以满足内存分配请求时,内核都会构建可用于搜索的区域列表。如果指定了 _ _GFP_DMA,则只搜索 DMA 区域:如果低地址没有内存可用,则分配失败。如果没有特殊标志,则搜索普通内存和 DMA 内存。
所以看起来标志 GFP_DMA 是 GFP_KERNEL 的子集。
dma_alloc_coherent() returns 已设置适当内存属性的地址范围,因此可以自然处理缓存效果。我们不需要对这些地址做任何缓存操作。
如果我们使用 kmalloc() 分配的地址进行 DMA 操作,那么我们需要根据传输方向执行额外的缓存操作,如缓存清理和缓存无效。
GFP_DMA 标志只是从 32 位机器上的 DMA 区域分配内存。