PCIe交换机后端设备触发SIGBUS故障,是否由设备本身导致?
咱们先明确一点:你的SIGBUS错误完全有可能是PCI设备本身导致的,结合你给出的内存映射信息(地址对应设备的resource2,也就是某个BAR空间),下面是几个设备端的常见诱因:
设备未正确响应访问请求
如果设备处于低功耗休眠状态、硬件出现故障,或者内部某些模块还没完成初始化,当你的进程发起对0xdc631400这个地址的读写时,设备无法返回正常的PCIe完成包(Completion Packet),反而返回了错误响应(比如Unsupported Request、Completion Timeout这类)。Linux内核会把这种PCIe总线错误转化为用户空间的SIGBUS信号,直接终止进程。BAR空间的地址范围未完全实现
你映射的resource2对应设备的某个BAR寄存器,系统是根据设备上报的BAR大小来分配地址空间的,但如果设备硬件本身并没有实现该BAR范围内的所有地址(比如厂商固件/硬件设计时只实现了部分区域,却上报了更大的空间),当进程访问到那些未实现的地址时,设备会返回错误响应,进而触发SIGBUS。设备内部总线或DMA故障
如果设备内部的总线(比如内部AHB/AXI总线)出现错误,或者DMA传输过程中发生溢出、地址错误,可能会导致对BAR区域的访问无法正常完成。这种情况下,设备会向PCIe总线上报错误,最终传递到用户进程就是SIGBUS。
当然,也不能完全排除PCIe交换机、CPU桥的问题,但从你描述的偶发特性和地址映射来看,设备本身的问题概率是很高的。你可以尝试:
- 换一个同型号的PCI设备测试,看是否还会出现相同错误;
- 查看内核日志(用
dmesg命令),里面通常会有PCIe错误的详细日志,能帮你定位是设备还是链路的问题; - 检查设备的固件版本,尝试更新到最新版本。
内容的提问来源于stack exchange,提问作者Matviy Kotoniy

