kmalloc中的缓冲区还是DMA安全缓冲区吗?

香芹酮

我正在为SPI连接的LCD编写帧缓冲驱动程序。我使用kmalloc分配缓冲区,该缓冲区很大-150KB。给定kmalloc分配缓冲区的方式,ksize报告使用更多内存的方式-大约256KB。

SPI spi_transfer结构采用指向tx和rx缓冲区的指针,这两个缓冲区都必须是DMA安全的。因为我希望tx缓冲区大约为16KB,我可以在kmalloced视频缓冲区中分配该缓冲区,并且仍然是DMA安全的吗?

这可以被认为是过早的优化,但是视频缓冲区中有太多的备用空间,很难使用它!基本上,分配的内存之间没有区别:

kmalloc(videosize)

kmalloc(PAGE_ALIGN(videosize) + txbufsize)

因此,可以将kptr返回并执行以下操作:

txbuf = (u8 *)kptr + PAGE_ALIGN(videosize);

我知道“ DMA安全”的部分要求是适当的对齐方式-与我认为的CPU缓存行大小相匹配-但是页面对齐是否可以这样做?

顺便说一句,我不确定tx和rx是否可以指向同一位置。spi.h标头也不清楚(实际上明显不清楚)。鉴于rx缓冲区永远不会超过几个字节,因此尝试找出麻烦来是很愚蠢的!

香芹酮

附带条件的答案似乎是肯定的。(特别是“比这还复杂”)

如果您通过__get_free_page *()或通用内存分配器(kmalloc)获取内存,则可以使用从那些例程返回的地址来往该内存的DMA。潜在的含义是,由于可以保证基础物理内存是连续的并且可以保证页面对齐的缓冲区位于高速缓存行边界上,因此kmalloc中的页面对齐缓冲区(即使跨越多个页面)也将是DMA安全的。

一个条件是该设备是否能够驱动整个总线宽度(例如:ISA)。因此,内存的物理地址必须在设备的dma_mask之内。

另一个是缓存一致性要求。这些以高速缓存行宽度的粒度运行。为了防止两个单独的内存区域共享一条缓存行,dma的内存必须恰好在缓存行边界处开始,而恰好在一个缓存行边界处结束。鉴于这可能是未知的,建议(DMA API文档)仅映射在页面边界上开始和结束的虚拟区域(因为如上所述,这些虚拟区域也保证是高速缓存行边界)。

在这种情况下,DMA驱动程序可以使用dma_alloc_coherent()分配DMA可用空间,以确保DMA区域不可缓存。由于这可能很昂贵,因此还存在一种流传输方法(用于单向通信),其中一致性限于写时进行缓存刷新。在先前分配的缓冲区上使用dma_map_single()。

就我而言,将tx和rx缓冲区传递给spi_sync而无需dma_map_single很好-spi例程将为我完成此工作。我可以自己使用dma_map_single以及unmap或dma_sync_single_for_cpu()来使所有内容保持同步。我现在不会打扰-驱动程序工作性能调整是一个更好的策略。

也可以看看:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章