如何进行TRUE重新扫描PCIe总线

时间:2015-09-01 14:57:31

标签: linux-kernel linux-device-driver pci-e hotplugging

我有一个FPGA(就像大多数人问这个问题一样)在我的Linux内核进行初始PCIe总线扫描和枚举之后进行配置。您可以猜到,FPGA实现了PCIe端点。

我想让PCIe内核重新枚举整个PCIe总线,这样我的FPGA就会出现,我可以加载我的驱动模块。我还希望能够为不同的配置交换FPGA负载。我的意思是,我希望能够:

  1. 启动Linux
  2. 配置FPGA
  3. 枚举PCIe端点和加载模块
  4. 删除PCIe端点
  5. 重新配置FPGA
  6. 重新枚举PCIe端点
  7. 全部无需重启Linux

    以下是其他地方提出但未解决问题的解决方案。

    echo 1 > /sys/bus/pci/rescan这似乎有效(仅在某些情况下),如果我想在首次枚举后热插拔FPGA负载,它就无法工作。

    这是一种相当侵入性的方法(我没有测试过),也有人在其他地方提出过。 https://community.freescale.com/thread/305355

    可以使用PCIe的Hotplug /电源管理设施来完成这项工作吗?如果是这样,有什么好的资源可以用于如何使用PCIe的Hotplug系统? (LDD并没有完全覆盖它)

3 个答案:

答案 0 :(得分:14)

通过echo 1 > /sys/bus/pci/rescan重新枚举PCIe总线/树是正确的解决方案。我们使用它的方式与您描述的方式相同。

我们正在使用echo 1 > $pcidevice/remove断开驱动程序与设备的连接,并将设备从树中分离出来。驱动程序(xillybus)没有卸载,只是断开连接。

更好的解决方案是仅重新扫描附加FPGA的节点。这减少了对系统的全面影响。

此技术用于RC3E FPGA云系统。

答案 1 :(得分:0)

来自医生

这里是在Windows中重设拉斯维加斯之前如何重设Vegas的方法。这基于供应商ID。

lspci -n | grep 1002: | egrep -v ".1"| awk '{print "find /sys | grep ""$1"/rescan" -| tac -;"}' | sh - | sed s/^/echo\ 1\ >\ "&/g | sed s/$/"/g

与devcon重新启动脚本类似,在启动后输入/etc/rc.local中的内容以重置您的Vegas。

echo 1 > "/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/rescan"
echo 1 > "/sys/devices/pci0000:00/0000:00:1c.5/0000:03:00.0/rescan"
echo 1 > "/sys/devices/pci0000:00/0000:00:1d.0/0000:06:00.0/rescan"
echo 1 > "/sys/devices/pci0000:00/0000:00:1d.1/0000:07:00.0/rescan"

答案 2 :(得分:0)

这实际上取决于FPGA上所做的更改。问题在于如何完成PCIe枚举和地址分配,尤其是如何配置PCIe交换机。分配必须作为深度优先搜索一次完成。完成此操作后,就不可能在不更改所有后续分配的情况下插入其他总线号或地址空间,这将需要重新加载所有相应的设备驱动程序。基本上,一旦枚举了总线并分配了地址,就无法在不重新枚举整个总线的情况下更改总体分配,这需要重新启动。在特定的PCIe端口上预分配资源可以缓解此问题,这是PCIe热插拔所必需的。

如果PCIe BAR配置没有更改,则通常执行删除/ posix_fadvise() /重新扫描就足够了,并且不需要重新启动。

如果BAR配置已更改,那么情况就不同了。如果新的BAR较小,则应该没有问题。但是,如果新的BAR较大或存在更多BAR,则如果没有足够的地址空间分配给设备所连接的交换端口,则无法为这些BAR分配地址空间,并且设备将无法枚举。在这种情况下,需要重新启动才能重新分配资源。别忘了还有32位BAR和64位BAR,这些BAR是从两个不同的地址空间池中分配的,因此更改BAR类型还可能需要重新启动才能重新枚举。

如果您要从无设备访问设备(即从空白的FPGA到已配置的FPGA),则可能需要重新分配总线号,这需要重新启动。