Linux kernel kmalloc中的缓冲区也是DMA安全缓冲区吗? 我正在为一个SPI连接的LCD编写一个帧缓冲驱动程序。我使用kmalloc来分配缓冲区,缓冲区相当大——150KB。考虑到kmalloc分配缓冲区的方式,ksize报告了使用更多内存的方式—256KB左右

Linux kernel kmalloc中的缓冲区也是DMA安全缓冲区吗? 我正在为一个SPI连接的LCD编写一个帧缓冲驱动程序。我使用kmalloc来分配缓冲区,缓冲区相当大——150KB。考虑到kmalloc分配缓冲区的方式,ksize报告了使用更多内存的方式—256KB左右,linux-kernel,linux-device-driver,dma,Linux Kernel,Linux Device Driver,Dma,SPI SPI_传输结构采用指向tx和rx缓冲区的指针,这两个缓冲区都必须是DMA安全的。由于我希望tx缓冲区大约为16KB,我可以在KAlloced视频缓冲区内分配该缓冲区,并且仍然是DMA安全的吗 这可能被认为是过早的优化,但视频缓冲区中有太多的空闲空间,不使用它会让人感觉很糟糕!基本上,以下各项之间的分配内存没有区别: kmalloc(videosize) 及 因此,可以将kptr返回并执行以下操作: txbuf = (u8 *)kptr + PAGE_ALIGN(videosize);

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

这可能被认为是过早的优化,但视频缓冲区中有太多的空闲空间,不使用它会让人感觉很糟糕!基本上,以下各项之间的分配内存没有区别:

kmalloc(videosize)

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

txbuf = (u8 *)kptr + PAGE_ALIGN(videosize);
我知道“DMA安全”的部分要求是与CPU缓存线大小的适当对齐,我相信…-但是,页面对齐不应该适合这种情况吗


另外,我不确定tx和rx是否可以指向同一个地方。spi.h头也不清楚(实际上明确不清楚)。考虑到rx缓冲区永远不会超过几个字节,试图找出答案来制造麻烦是愚蠢的

答案似乎是肯定的,但有附带条件。(特别是“比那更复杂”)

如果您通过uu get_free_page*()或通用内存分配器(kmalloc)获取内存,那么您可以使用这些例程返回的地址对该内存进行DMA。潜在的含义是,kmalloc中的页对齐缓冲区(即使跨越多个页)将是DMA安全的,因为底层物理内存保证是连续的,页对齐缓冲区保证位于缓存线边界上

一个附带条件是设备是否能够驱动全总线宽度(例如:ISA)。因此,存储器的物理地址必须在设备的dma_掩码内

另一个是缓存一致性要求。它们以缓存线宽度的粒度进行操作。为了防止两个独立的内存区域共享一条缓存线,dma的内存必须精确地从缓存线边界开始,精确地在一条缓存线边界结束。考虑到这一点可能未知,建议(DMA API文档)仅映射在页面边界上开始和结束的虚拟区域(如上所述,这些虚拟区域也保证是缓存线边界)

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

在我的例子中,在不使用dma_map_single的情况下将tx和rx缓冲区传递给spi_sync是可以的-spi例程将为我完成这项工作。我可以使用dma_map_single以及unmap或dma_sync_single_for_cpu()来保持一切同步。不过,我现在不想麻烦了——在驾驶员工作后调整性能是一个更好的策略

另见:


也许可以尝试将您的代码构造为直接写入DMA的内存,而不是kmalloc缓冲区?为什么要将
kmalloc
用于视频缓冲区?而不是“获取免费”页面?不应该有任何区别。。。他们都很安全。我可以半回答我自己的问题——如果我与一个页面对齐,我相信这将解决所有可能的缓存一致性问题,即使这是一个过度的问题,而无需我研究TLB的内容。非常简洁的答案。但也有一些疑问:1。为什么dma_alloc_相干昂贵?它在所有芯片组上都很昂贵,还是仅在那些具有严格缓存更新要求的芯片组上昂贵,而这些芯片组可能需要绕过缓存更新要求?2.您能否以类似的简洁方式详细介绍流媒体方法?
txbuf = (u8 *)kptr + PAGE_ALIGN(videosize);