我注意到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)
我想知道为什么有必要了解取消映射的方向和属性。最初我认为映射有点像malloc
和free
。但看到这一点,我想知道以下内容是否合法:
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
?
答案 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!