4

我正在更新一个较旧的 linux 驱动程序,该驱动程序通过 DMA 将数据传输到用户空间页面,这些页面通过get_user_pages().

我的硬件是一个新的基于 x86 Xeon 的主板,具有 12GB 的 RAM。

驱动程序将数据从 VME 获取到 PCIe FPGA,并且应该将其写入主存储器。我dma_map_pages()为每一页做一个,我检查它dma_mapping_error()并将返回的物理 DMA 地址写入 DMA 控制器的缓冲区描述符。然后我启动 DMA。(我们还可以在 FPGA 跟踪器中看到传输开始)。

但是,当我得到 DMA 完成 IRQ 时,我看不到任何数据。对于控制,我可以通过 PIO 模式访问相同的 VME 地址空间,并且可以正常工作。我还尝试将值写入用户页面的 page_address(page) 并且应用程序可以看到这些。一切都好。

深入研究这个问题,我检查了像 DMA-API.txt 这样的常用文档,但我找不到任何其他方法,在其他驱动程序中也找不到。

我的内核是一个自编译的 4.4.59 64 位,各种调试(调试 DMA-API 等)设置为是。

我还尝试通过驱动程序/iommu/ 来查看这里的调试可能性,但那里只有一些 pr_debugs。

有趣的是:我有另一个驱动程序,一个以太网驱动程序,它支持连接到 PCI 的 NIC。这个工作没有问题!

在转储和比较检索到的 DMA 时dma_addr_t,我看到了这一点:

NIC 驱动程序通过dma_alloc_coherent()缓冲区描述符等分配内存,它的地址在“lower 4 GB”中:

 [ 3127.800567] dma_alloc_coherent: memVirtDma = ffff88006eeab000, memPhysDma = 000000006eeab000
 [ 3127.801041] dma_alloc_coherent: memVirtDma = ffff880035d9b000, memPhysDma = 0000000035d9b000
 [ 3127.801373] dma_alloc_coherent: memVirtDma = ffff88006ecd4000, memPhysDma = 000000006ecd4000

VME 驱动程序,dma_map_page'ing 用户空间页面大于 4GB,DMA 地址看起来不同:0xffffe010(与应用程序有偏移)。

pageAddr=ffff88026b4b1000 off=10 dmaAddr=00000000ffffe010 length=100

DMA_BIT_MASK(32)在两个驱动程序中都设置了,我们的 FPGA 内核是 32 位宽的。

问题:我是否必须具备特殊的先决条件才能使此 DMA 工作?我读到 highmem 内存不能用于 DMA,现在还是这样吗?

dmesg 的一部分:

[    0.539839] debug: unmapping init [mem 0xffff880037576000-0xffff880037ab2fff]
[    0.549502] DMA-API: preallocated 65536 debug entries
[    0.549509] DMA-API: debugging enabled by kernel config
[    0.549545] DMAR: Host address width 46
[    0.549550] DMAR: DRHD base: 0x000000fbffc000 flags: 0x1
[    0.549573] DMAR: dmar0: reg_base_addr fbffc000 ver 1:0 cap     8d2078c106f0466 ecap f020df
[    0.549580] DMAR: RMRR base: 0x0000007bc14000 end: 0x0000007bc23fff
[    0.549585] DMAR: ATSR flags: 0x0
[    0.549590] DMAR: RHSA base: 0x000000fbffc000 proximity domain: 0x0
[    0.549779] DMAR: dmar0: Using Queued invalidation
[    0.549784] DMAR: dmar0: Number of Domains supported <65536>
[    0.549796] DMAR: Setting RMRR:
[    0.549809] DMAR: Set context mapping for 00:14.0
[    0.549812] DMAR: Setting identity map for device 0000:00:14.0     [0x7bc14000 - 0x7bc23fff]
[    0.549820] DMAR: Mapping reserved region 7bc14000-7bc23fff
[    0.549829] DMAR: Set context mapping for 00:1d.0
[    0.549831] DMAR: Setting identity map for device 0000:00:1d.0     [0x7bc14000 - 0x7bc23fff]
[    0.549838] DMAR: Mapping reserved region 7bc14000-7bc23fff
[    0.549845] DMAR: Prepare 0-16MiB unity mapping for LPC
[    0.549853] DMAR: Set context mapping for 00:1f.0
[    0.549855] DMAR: Setting identity map for device 0000:00:1f.0 [0x0 -     0xffffff]
[    0.549861] DMAR: Mapping reserved region 0-ffffff
[    0.549892] DMAR: Intel(R) Virtualization Technology for Directed I/O
...
[    0.551725] iommu: Adding device 0000:00:00.0 to group 10
[    0.551753] iommu: Adding device 0000:00:01.0 to group 11
[    0.551780] iommu: Adding device 0000:00:01.1 to group 12
[    0.551806] iommu: Adding device 0000:00:02.0 to group 13
[    0.551833] iommu: Adding device 0000:00:02.2 to group 14
[    0.551860] iommu: Adding device 0000:00:03.0 to group 15
[    0.551886] iommu: Adding device 0000:00:03.2 to group 16
[    0.551962] iommu: Adding device 0000:00:05.0 to group 17
[    0.551995] iommu: Adding device 0000:00:05.1 to group 17
[    0.552027] iommu: Adding device 0000:00:05.2 to group 17
[    0.552059] iommu: Adding device 0000:00:05.4 to group 17
[    0.552083] iommu: Adding device 0000:00:14.0 to group 18
[    0.552134] iommu: Adding device 0000:00:16.0 to group 19
[    0.552166] iommu: Adding device 0000:00:16.1 to group 19
[    0.552191] iommu: Adding device 0000:00:19.0 to group 20
[    0.552216] iommu: Adding device 0000:00:1d.0 to group 21
[    0.552272] iommu: Adding device 0000:00:1f.0 to group 22
[    0.552305] iommu: Adding device 0000:00:1f.3 to group 22
[    0.552332] iommu: Adding device 0000:01:00.0 to group 23
[    0.552360] iommu: Adding device 0000:03:00.0 to group 24
[    0.552437] iommu: Adding device 0000:04:00.0 to group 25
[    0.552473] iommu: Adding device 0000:04:00.1 to group 25
[    0.552510] iommu: Adding device 0000:04:00.2 to group 25
[    0.552546] iommu: Adding device 0000:04:00.3 to group 25
[    0.552575] iommu: Adding device 0000:05:00.0 to group 26
[    0.552605] iommu: Adding device 0000:05:00.1 to group 27
4

1 回答 1

2

为了完整起见,我们找到了答案。完全不同的原因:FPGA PCIe 内核中的 PCIe 协议错误...

于 2017-10-05T11:47:48.387 回答