近期有用户在使用我们的PCIe 6.0 switch卡连接Nvidia Mellanox CX系列网卡的时候问到一个关于PCIe 拓扑树(topology tree)显示的问题。我们知道,在 PCIe 系统和服务器硬件运维中, lspci 输出的树状图(Topology)是排查设备链路、拓扑结构和 Bus 号分配问题的核心工具。今天就来结合我们用户的这个实际问题,来详细拆解如何阅读 PCIe Tree、解答关于 Bus 号范围(Upstream/Downstream)看起来好像不一致的疑问,并盘点全球工程师最常用的 lspci 参数与经典实战案例。
lspci-t 拓扑树?首先,我们用一个标准的、干净的 lspci-t 拓扑图范本来做教学:
拓扑图的基本阅读逻辑:
-[0000:80]-:表示 PCIe Domain : Root Bus (根总线)。这里代表 Domain 为 0000,Root Bus 号是 80。通常对应 CPU 内部的 Host Bridge。+-04.1:代表在 Bus 80 上的 Device 04, Function 1(即 80:04.1)。这是一个 Root Port(根端口),本质上是一个 PCI-to-PCI 桥。-[81-94]:紧跟在桥设备后面的方括号,表示该桥所能控制/预留的子总线范围(Subordinate Bus Range)。----00.0:表示下一级总线上的设备。例如 -[81-94]----00.0 意味着,在进入次级总线后,遇到的第一个设备是 81:00.0。在随附的截图中,有两处画红线的 Bus 范围区间:
-[81-94]-[82-93]这属于非常经典的 PCIe 桥的 Bus 资源分配与嵌套(Nested Bridges)。
在 PCIe 规范中,每一个 PCI-to-PCI Bridge(包括 Root Port, Switch Upstream Port, Switch Downstream Port)在配置空间里都有三个关于 Bus 的寄存器:
80:04.1:81:00.0:82-93 的内部,Switch 拆出了非常多的下游端口(Downstream Ports),例如 00.0, 01.0, 02.0 直到 10.0。00.0 端口直接分配了 Bus 83 给网卡(Mellanox ConnectX-6 Dx),而网卡拥有两个 Function( 00.0 和 00.1)。01.0 分配了 Bus 84, 02.0 分配了 Bus 85……以此类推,直到 10.0 分配了 Bus 93。你会发现 Root Port 批了 81-94,但底下的 Switch 只用了 82-93,94 消失了。
这是因为 BIOS/系统内核在进行 PCIe 热插拔预留(Hotplug Reservation)。系统为了防止用户以后在这个 Root Port 附近插入新的扩展卡或切分设备,故意在最外层(Root Port)多留了一个 94 号总线。如果未来有新硬件插入,可以直接将 94 分配给新硬件,而不需要重新打乱、刷新整个 81-93 已经分配好的现有拓扑结构。
lspci 命令与实战案例以下是根据全球系统工程师和内核开发者的使用频度,整理出的最常用 lspci 参数及其实战解决的问题:
| 常用命令组合 | 全球频度 | 核心作用描述 |
|---|---|---|
lspci | ||
lspci-tv | ||
lspci-vvv | ||
lspci-k | ||
lspci-nn | ||
lspci-s<BDF> |
lspci-vvv-s83:00.0|grep-E"LnkCap|LnkSta"当你在测试 Mellanox 网卡或 NVMe 盘时,发现性能死活跑不满(例如原本 100G 的网卡只能跑 50G)。
-vvv 可以 dump 出 PCIe 能力寄存器。 LnkCap(Link Capability)代表硬件设计最高支持的能力(如 Speed16GT/s,Widthx16,即 PCIe 4.0 x16)。而 LnkSta(Link Status)代表当前实际运行的状态。如果实际状态显示 Speed8GT/s,Widthx8,说明硬件可能由于金手指脏污、机箱震动或信号干扰,在物理层发生了解宽和降速。使用该命令能一秒定位物理链路故障。
lspci-nn|grep-i mellanox当系统里装了一块新网卡或加速卡,操作系统无法识别它(显示为 Unknowndevice),或者你在写自动化脚本、需要精确匹配芯片型号。
标准的 lspci 只输出人能看懂的文本(依赖本地的 pci.ids 数据库)。如果数据库没更新,就看不到名字。加上 -nn 后,会强制输出十六进制的数字,例如 [15b3:101d](15b3 是 Mellanox 厂商 ID,101d 是设备 ID)。有了这个绝对唯一的数字 ID,工程师可以直接去谷歌查到该芯片的官方型号,或者直接写进内核驱动的 match_table 里去加载驱动。
lspci-k-s83:00.0在配置网络 DPDK 高性能转发或者安装 NVIDIA/AMD 显卡驱动时,经常需要确认当前设备是被内核自带的开源驱动(如 nouveau、 mlx5_core)接管,还是被用户态驱动(如 vfio-pci)接管。
使用 -k 参数会明确输出两行:
Kerneldriverinuse:mlx5_core (当前正在生效的驱动)
Kernelmodules:mlx5_core (系统里可供选择的驱动模块)
这能让装驱动、切驱动的运维过程变得极其透明,防止“驱动没装上”或“驱动冲突”导致的各种玄学罢工。
更多PCIe5&6.0, CXL, NVMe SSD, SAS/SATA, NVMe over Fabric (NVMoF), NAND,新型存储技术NVM(RRAM/ReRAM, FRAM/FeRAM, MRAM, PCM, 3D-NOR, SRAM/DRAM等) DDR5/LPDDR5以及UFS测试方面的问题想咨询,可以查看Saniffer公司2026.2.24最新更新的测试工具白皮书15.1版本,我们已经整理收录在Saniffer公众号的【白皮书】菜单中。
欢迎关注Saniffer公众号,点击底部菜单栏即可免费获取。如有任何技术问题,也可直接在公众号内留言交流。