It'*_*ete 6 linux driver fpga xilinx pci-e
我目前正在使用Xilinx XDMA驱动程序(请参阅此处获取源代码:XDMA Source),并且我试图让它运行(在你问之前:我已经联系了我的技术支持联系人,Xilinx论坛上到处都是人有同样的问题).但是,我可能在Xilinx的代码中找到了一个障碍,这对我来说可能是一个交易破坏者.我希望有一些我不会考虑的事情.
首先,驱动程序有两种主要模式,AXI-Memory Mapped(AXI-MM)和AXI-Streaming(AXI-ST).对于我的特定应用,我需要AXI-ST,因为数据将持续从设备流出.
编写驱动程序以利用分散 - 收集列表.在AXI-MM模式下,这是有效的,因为读取是相当随机的事件(即,没有数据流出设备,而用户空间应用程序只是在需要时请求数据).因此,建立DMA传输,传输数据,然后拆除传输.这是一个组合get_user_pages()
,pci_map_sg()
和pci_unmap_sg()
.
对于AXI-ST来说,事情变得奇怪,源代码远非正统.驱动程序分配一个循环缓冲区,数据意味着连续流入.此缓冲区的大小通常有些大(我的设置大小为32MB),因为您希望能够处理用户空间应用程序忘记驱动程序的瞬态事件,然后可以解决传入的数据.
这里的事情变得很糟糕......循环缓冲区是使用分配的,vmalloc32()
并且来自该分配的页面的映射方式与用户空间缓冲区处于AXI-MM模式(即使用pci_map_sg()
接口)的方式相同.其结果是,因为循环缓冲器的设备和CPU之间共享,每个read()
呼叫需要我打电话pci_dma_sync_sg_for_cpu()
和pci_dma_sync_sg_for_device()
,这绝对会破坏我的表现(我不能与设备跟不上!),因为这会作用于整个缓冲区.有趣的是,Xilinx从未在代码中包含这些同步调用,因此我首先知道在编辑测试脚本以在退出之前尝试多个DMA传输并且生成的数据缓冲区已损坏时,我遇到了问题.
结果,我想知道如何解决这个问题.我已经考虑过重写代码来构建我自己分配的缓冲区pci_alloc_consistent()/dma_alloc_coherent()
,但这说起来容易做起来难.也就是说,代码被设计为假设在任何地方使用分散 - 收集列表(在分散 - 收集列表和FPGA理解的内存描述符之间似乎存在奇怪的专有映射).
有没有其他API调用我应该知道?我是否可以pci dma_sync_single_for_cpu()
通过某种转换机制使用"单一"变体(即)来同步整个缓冲区?或者,是否有一些函数可以使循环缓冲区分配vmalloc()
相干?
好吧,我想通了。
基本上,我对有关同步 API 的内核文档的假设和/或理解是完全错误的。也就是说,我在两个关键假设上是错误的:
read()
吞吐量增加了一倍。read()
调用中,我弄清楚哪些页面将受到调用的影响copy_to_user()
(即将从循环缓冲区中复制哪些页面),并且只同步我关心的那些页面。基本上,我可以调用诸如我认为副本将从哪里开始以及pci_dma_sync_sg_for_cpu(lro->pci_dev, &transfer->sgm->sgl[sgl_index], pages_to_sync, DMA_FROM_DEVICE)
数据的页数有多大之类的内容。sgl_index
pages_to_sync
通过上述两项更改,我的代码现在满足了我的吞吐量要求。
归档时间: |
|
查看次数: |
4068 次 |
最近记录: |