我可以使用从 DeviceA 上的 dma_alloc_coherent 返回的地址在 DeviceB 上调用 dma_map_single() 吗?

问题描述

我正在编写需要在多个 PCIE 设备之间使用 DMA 内存的自定义 linux 驱动程序。我有以下情况:

  1. 我正在使用 dma_alloc_coherent 为 DeviceA 分配内存
  2. 然后我使用 DeviceA 来填充内存缓冲区。

到目前为止一切都很好,但此时我想 DMA 内存到 DeviceB,我不确定这样做的正确方法。

现在我使用 DeviceB 调用 dma_map_single 从设备 A 上调用的 dma_alloc_coherent 返回的地址。这 似乎在 x86_64 中工作正常,但感觉就像我违反了规则 因为:

  1. dma_map_single 应该使用从 kmalloc(“和朋友”)分配的内存来调用。使用从另一个设备的 dma_alloc_coherent 调用返回的地址调用是否有问题?

  2. 如果#1 是“ok”,那么我仍然不确定是否有必要调用 dma_map_single 内存所需的 dma_sync_* 函数。由于内存最初是从 dma_alloc_coherent 分配的,它应该是未缓存的内存,所以我相信答案是“不需要 dma_sync_* 调用”,但我不确定。

我担心我只是幸运地拥有这份工作和未来 内核更新会让我崩溃,因为我不清楚我是否正确遵循 API 规则。 我的代码最终也必须在 ARM 和 PPC 上运行,所以我需要确保我以独立于平台的方式做事,而不是使用一些 x86_64 架构技巧。

我以此作为参考: https://www.kernel.org/doc/html/latest/core-api/dma-api.html

解决方法

  1. dma_alloc_coherent() 的作用与 __get_free_pages() 类似,但作为大小粒度而不是页面,所以我猜这里没有问题。
  2. 对于任何特定于平台的问题,请先在 dma_mapping_error() 之后调用 dma_map_single()dma_sync_*() 助手由流式 DMA 操作使用,以保持设备和 CPU 同步。至少需要 dma_sync_single_for_cpu(),因为设备修改缓冲区访问状态需要在 CPU 使用之前同步。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...