背景
有些时候知道某个网卡的宣称的物理极限速率,但是实际插入到服务器上由于某些设置、物理接口限制(比如x4 x8)或者其他拓扑带来的变化,造成实际生效的速率并非理论值。此时如何得知实际的PCIe上的实际速率?
方法
方法1:通过lspci获得
根据PCIe的单lane的速率 * 生效几个lane就可以得出。
一般单lane速率根据PCIe的代数决定。比如PCIe Gen3就是8G。 Gen5 32G。详细参考兄弟篇PCIe版本发布历史
对于网卡而言根据这个信息可以看到网卡在PCIe链路上的速率。
这些信息通过lspci -s 0000:01:00.0 -vvv
可以获得,lspci读取的PCIe的配置空间中的Capabilities获得。以及在subsystem中也会描述。
方法2:通过sysfs获取
# 最大值
cat /sys/bus/pci/devices/0000\:01\:00.0/max_link_speed
cat /sys/bus/pci/devices/0000\:01\:00.0/max_link_width
# 当前值
cat /sys/bus/pci/devices/0000\:01\:00.0/current_link_speed
cat /sys/bus/pci/devices/0000\:01\:00.0/current_link_width
通过sysfs的bus中pcie的设备中获取他在PCIe层的最大速率和最大带宽。这里最大速率和PCIe的Gen相关width和实际的插槽和网卡相关。这些值是从PCIe的配置空间读取的,驱动加载的时候读取更新。
实操
lspci查看
# 获取 PCIe 的 BDF
ethtool -i enp1s0f0
# 获取PCIe的详细信息
lspci -s 0000:01:00.0 -vvv
实操:
可以看到可以同多sybsystem中直接看到是x8,并且根据Gen3的速率8GT/s*8=64GT/s。但是这里是理论的值。
并且下面在第一个Capabilities中有相关信息,表示是一个Endpoint,并且有他的LnkCap
是8GT/s的速率,并且Width是x8。这个直接是从配置空间读取的硬件规格值。还有实际的生效值在LnkSta
中,可以看到是8GT/s和Width x8,这两个相乘也是64GT/s
这些值其实网卡驱动加载的时候也会读取到PCIe的驱动框架中
sysfs查看
查看最大值:
查看当前值:
其他
如何一次查看服务器上所有的PCIe当前的速率:cat /sys/bus/pci/devices/*/current_link*
综述
本文记录两种方式获取PCIe网卡的单lane速率和lane数量,包括规格和实际生效情况。分别从PCIe的配置空间通过lspci实时获取以及通过sysfs从内核驱动中获取。(而且这里有个重点,就是sysfs是初始化获取,假设是开发网卡的PCIe功能设置底层速率不通知上层,可能两者不一致,这是一种debug的方式)。