PCIe - DMA:一致性与流式内存

PCIe - DMA: Consistent vs. Streaming Memory

目前我正在为 Linux 添加 DMA 到我的 PCIe 驱动程序。当我阅读文档时,它通过使用 API:

提到了一致的或连贯的内存
pci_set_consistent_dma_mask(...)

但从未真正谈论过为什么要使用它或它的作用。它似乎提到调用函数以获得最佳实践和未来验证。我能收集到的最好的信息是一致的 DMA 内存没有缓存效果,并且内存是在设备 (FPGA) 和 CPU 之间写入的,一旦设置正确(假设我读取正确),没有任何 software/driver 干预。 所以我的问题是:

  1. 假设一个 PCIe 设备不需要一致性内存那么为什么会有人使用它,或者在什么情况下使用一致性内存?
  2. 如果我使用一致内存,那么我不需要需要在 DMA 的 PCIe 驱动程序中实现中断吗?如果为真,那么用户空间代码和设备如何知道传输已发生?
  3. 如果我连续传输很多小数据包,~50 字节,偶尔传输较大的数据包,~6 kB,哪个 DMA 内存更好:一致还是流?

1)假设您想通过 PCIE 高速传输大量数据。你必须使用scatter/gather列表,你可以使用一致的内存为FPGA准备这个列表,所以FPGA可以非常快速地读取这个列表然后进行传输。

2)当然你需要中断,否则你必须使用非常慢且不可靠的轮询

3)如果你使用更大的一致性内存,你可以最小化interrupt/polling开销,所以它们更快,但是windows通常不允许你分配大的一致性内存。

这样想:"Consistent" 意味着它会在 CPU 和总线 之间自动保持一致,而不需要做任何专门的同步操作 。例如 - 假设我有一个用于入站和出站数据包的内存环。它的寿命将是系统使用的整个时间,我将检查它 所有 时间。我希望这 总是 一致,因为如果不是这样,我将不得不(手动)刷新或同步缓存,如果这样做代价高昂,我必须这样做 非常次我触摸戒指 - 那将是噩梦。

另一方面 - 让我们以我正在传输的单个数据缓冲区为例。我不是 "one off" 交易。我可以让设备传输它——也许它需要很多 PCI 周期来完成 DMA。也许这 不一致 。没关系 - 但当它 完成后 我可以 flush/sync caches/force 保持一致性。如果这样做需要一点额外的时间 - 没问题 - 因为我只做了一次 一次

所以你可能会问 "why not make everything consistent"。答案是通常有 一些 级别的开销来使事情保持一致。根据体系结构,这个 可能 很重要。因此,在这种情况下,有一些规定允许不一致的(流式)映射不实现缓存一致性(但需要 explicit 同步)。因此,允许不一致的传输可以让您获得一些性能。

还要记住 - 在某些情况下,您 永远不会 需要任何一致性。例如 - 从网络设备读取缓冲区到内存,然后将该内存写入磁盘控制器。此数据可能根本不会被 CPU read/used - 所以为什么要在 CPU 缓存上放置任何开销来跟踪它。

至于您对 "interrupt" 的评论 - 这有点奇怪。在 "normal" 情况下 - 你可能在 consistent 内存中有一个控制结构(比如 Tx/Rx 环)你可以 poll 告诉您交易是否完成。但实际传输的数据将在 不同的 内存中,可能是流式或不一致的。