直接查看 lspci -vvv 输出里的 LnkSta 行,它显示的是当前真实协商的链路速度和带宽,并非设备标称能力,也非插槽物理规格。先把这个关键结论说清楚,后面再详细展开讲解。

为什么只用 lspci -vvv | grep "Speed" 会出错
不少朋友图省事,直接运行 lspci -vvv | grep "Speed",结果看到输出:Speed 16GT/s,心想“挺好,跑在PCIe 4.0上了”。但实际上呢?这条命令把 LnkCap(设备支持上限)、DevCap(设备能力)和 LnkSta(实际状态)混在一起输出,很容易被假象误导。举个例子:
LnkCap: Speed 16GT/s, Width x4这是设备本身支持PCIe 4.0 x4规格,不代表它当前正运行在该速率下LnkSta: Speed 8.0GT/s, Width x2才是真实情况——它实际上只协商到了PCIe 3.0 x2- 某些老旧网卡或BMC直连设备,
LnkSta行甚至完全消失不见,如果只靠grep扫一遍输出,这类链路异常就会被悄然忽略
因此核心要点十分明确:务必查看 LnkSta 行,不要被 LnkCap 欺骗。
必须加 sudo 才能看到 LnkSta
普通用户执行 lspci -vvv 时,PCIe配置空间中的部分寄存器(尤其是链路状态寄存器)根本无法读取。结果就是 LnkSta 行为空、字段丢失,甚至整行消失。这不是命令没有输出,而是权限不足。
- 务必使用
sudo lspci -vvv,否则诊断结果无效 - 如果加了
sudo仍然看不到LnkSta,需要检查内核是否启用了CONFIG_PCIEASPM,或者BIOS是否关闭了“PCIe Link State Reporting”功能 - 遇到多功能设备(例如NVMe控制器包含Function 0和Function 1),
LnkSta可能藏在次要功能里,需要单独执行sudo lspci -s 00:1d.1 -vvv来查看
比 lspci 更可靠的验证方式:读取 /sys/bus/pci/devices/xxx/current_link_speed
lspci 依赖于用户空间工具解析配置空间,而 /sys 下的值由内核直接从硬件寄存器读取,更贴近运行时的真实状态。这种方式尤其适合脚本批量采集数据,或者在 lspci 失效时作为兜底方案。
- 首先定位设备地址:
lspci | grep -i nvme→ 得到类似0000:09:00.0的地址 - 检查路径是否存在:
ls /sys/bus/pci/devices/0000:09:00.0/ - 读取当前速率:
cat /sys/bus/pci/devices/0000:09:00.0/current_link_speed(输出为纯数字,例如8.0) - 读取最大能力:
cat /sys/bus/pci/devices/0000:09:00.0/max_link_speed;如果两者不一致,说明链路已经发生了降速
真正容易被忽略的一点:LnkSta 显示 Speed 0.0GT/s 或字段为空,并非“速度很慢”,而是链路根本没有建立起来。此时应该去查看 dmesg | grep -i pcie,检查供电、BIOS中PCIe设置是否被禁用,或者设备是否被识别为 disabled 状态。
