Linux kernel PCI MMIO读取数据延迟的原因是什么?

Linux kernel PCI MMIO读取数据延迟的原因是什么?,linux-kernel,fpga,pci-e,Linux Kernel,Fpga,Pci E,我们的团队目前正在开发定制设备。 Cyclone V板上插入了基于COM Express amd64的PC。该板用作PCIe本机端点。它先打开电脑,然后再打开电脑。PC上运行的linux内核为4.10,一些驱动程序和软件通过MMIO与PCI BAR0协同工作。 在linux终端第一次重新启动之前,系统工作正常。在下一次启动时,MMIO读访问中断,而MMIO写访问正常 假设有两个要读取的偏移量A和B,分别为0xa和0xb。现在,如果我们从这些偏移量中读取字节,则在检索到的值中似乎有8次读取操作的延

我们的团队目前正在开发定制设备。
Cyclone V板上插入了基于COM Express amd64的PC。该板用作PCIe本机端点。它先打开电脑,然后再打开电脑。PC上运行的linux内核为4.10,一些驱动程序和软件通过MMIO与PCI BAR0协同工作。
在linux终端第一次重新启动之前,系统工作正常。在下一次启动时,MMIO读访问中断,而MMIO写访问正常

假设有两个要读取的偏移量A和B,分别为0xa和0xb。现在,如果我们从这些偏移量中读取字节,则在检索到的值中似乎有8次读取操作的延迟:

  • 读取十次-每次返回0xa
  • 读取B八次-每次返回0xa
  • 读取B十次-每次返回0xb
  • 读取一次-返回0xb
  • 读取B七次-每次返回0xb
  • 读取B一次-返回0xa
  • 读取B十次-返回0xb
  • 如果偏移量A和B在同一个64位字内,则所有工作方式与预期相同。
    MMIO访问是通过readb/readw/readl/readq函数完成的,实际使用的函数根本不会影响此延迟。
    顺序重新引导可能会修复或再次中断MMIO读取

    从linux的角度来看,mmiotrace提供了相同的图片,但数据已损坏。
    从设备角度看,signaltap逻辑分析仪显示PCIe核心总线上的有效数据值。
    我们没有PCI总线分析仪设备,因此我们不知道是否有可能检查这两点之间的数据交换。

    这种行为的原因是什么?如何修复?

    您需要将资源标记为不可缓存区域。事实上,您只是读取了CPU缓存线,而不是真正的总线读取。@0andriy,谢谢您的回复。正如我从pci_resource_flags()调用结果中看到的,没有IORESOURCE_CACHEABLE标志集。这是总线的角度,我所说的是CPU对同一区域的角度。例如,x86有一组定义内存区域标志的MTRR寄存器。@0andriy,似乎不是这样。pcim_iomap()在内部使用ioremap_nocache(),默认情况下,它会提供_PAGE_CACHE_MODE_UC_减号。强制ioremap_uc()用法没有改变任何内容。即使两次读取之间有5分钟的延迟,也不会改变任何东西。MMIO写入不受影响,并且总是按顺序进行。在完全断电后的第一次开机时,系统工作正常。是否总是延迟8秒?