Linux Streaming DMA ReMapping没有取消映射

时间:2015-01-18 01:31:07

标签: linux-device-driver

我注意到pci_unmap_sg的签名(我显示dma_unmap_sg_attrs,由pci_unmap_sg通过两个宏调用并具有明确的参数命名)包括方向和属性。

static inline void dma_unmap_sg_attrs(
   struct device *dev,
   struct scatterlist *sg, 
   int nents,
   enum dma_data_direction dir, 
   struct dma_attrs *attrs)

我想知道为什么有必要了解取消映射的方向和属性。最初我认为映射有点像mallocfree。但看到这一点,我想知道以下内容是否合法:

dma_map_sg_attrs(..., dir=DMA_BIDIRECTIONAL,...);
...
dma_unmap_sg_attrs(..., dir=DMA_FROM_DEVICE ,...);
//continue use in TO_DEVICE direction

dma_map_sg_attrs(..., dir=DMA_TO_DEVICE,...);
...
dma_map_sg_attrs(..., dir=DMA_FROM_DEVICE ,...);
//start bidirectional use

我也可以这样做(如果它们不能直接相互映射,则通过DMA将数据从一个设备流式传输到另一个设备):

dma_map_sg_attrs(dev1, ..., dir=DMA_FROM_DEVICE ,...);
dma_map_sg_attrs(dev2, ..., dir=DMA_TO_DEVICE ,...);

我尝试深入研究该函数,但在get_dma_ops处结束,它从全局获取函数指针。但是如何进一步遵循此代码是另一个question


更新

我发现同步api更令人困惑:

pci_dma_sync_sg_for_cpu(
  struct pci_dev *hwdev,
  struct scatterlist *sg,
  int nelems,
  int direction
)

这个api知道方向的原因是什么? api是否无法记住原始的映射方向,如果我们仅映射为sync_for_cpu,它是否会释放DMA_TO_DEVICE

2 个答案:

答案 0 :(得分:1)

答案将是简单而强大的同时。这取决于您对所使用的CPU架构的了解程度。 DMA的问题是CPU缓存。 CPU缓存必须与DMA一致。因此,我们在同步API中有不同的指示,因为我们可以从双方DMA和CPU 访问数据。就像您所知,同步API是地图API中方向参数的原因。

P.S。它无论如何都不是全面的答案。为此,您必须阅读具体的文献和文献。我建议你从Documentation/DMA*.txt文件开始。

答案 1 :(得分:0)

来自Andy的tipps是正确的,而我认为大多数DMA_ATTR_ *都不会帮助我,因为我的设备执行了排序,因此内核无法处理其中的一些,但是如果你看一下{{1你找到了(来自DMA-attributes.txt):

 71 DMA_ATTR_SKIP_CPU_SYNC
 72 ----------------------
 73 
 74 By default dma_map_{single,page,sg} functions family transfer a given
 75 buffer from CPU domain to device domain. Some advanced use cases might
 76 require sharing a buffer between more than one device. This requires
 77 having a mapping created separately for each device and is usually
 78 performed by calling dma_map_{single,page,sg} function more than once
 79 for the given buffer with device pointer to each device taking part in
 80 the buffer sharing. The first call transfers a buffer from 'CPU' domain
 81 to 'device' domain, what synchronizes CPU caches for the given region
 82 (usually it means that the cache has been flushed or invalidated
 83 depending on the dma direction). However, next calls to
 84 dma_map_{single,page,sg}() for other devices will perform exactly the
 85 same synchronization operation on the CPU cache. CPU cache synchronization
 86 might be a time consuming operation, especially if the buffers are
 87 large, so it is highly recommended to avoid it if possible.
 88 DMA_ATTR_SKIP_CPU_SYNC allows platform code to skip synchronization of
 89 the CPU cache for the given buffer assuming that it has been already
 90 transferred to 'device' domain. This attribute can be also used for
 91 dma_unmap_{single,page,sg} functions family to force buffer to stay in
 92 device domain after releasing a mapping for it. Use this attribute with
 93 care!