2. ASPM开启后的预期行为:链路速率协商与电源状态切换对带宽的影响

做ASPM故障排查,第一步得搞清楚——什么叫做“正常”。

很多人一看到链路速度掉到Gen1,就喊着“降速了!降速了!”。其实,这很可能就是ASPM预期的行为。你想想看,如果设备空闲时还跑在8GT/s,那功耗控制就白设计了。

这一章,我们来拆解两个核心概念:

  • 链路速率协商:ASPM是如何让链路在空闲时“慢下来”的?
  • 电源状态切换:L0→L0s→L1,这些状态切换对实际带宽到底有多大影响?

我把话先说清楚:我们讲的是“预期行为”。只有先知道什么是“正确”的,才能精准地抓住“异常”。

2.1 链路速率协商:不是你想降就能降

PCIe链路的速率和宽度,是两端设备通过Training Sequence协商出来的。这个过程发生在链路初始化阶段,也发生在链路从低功耗状态唤醒时。

ASPM开启后,设备进入L1状态时,链路的物理连接会被断开。当需要重新传输数据时,链路必须重新进行Training。这个重新Training的过程,就是速率协商的窗口。

我个人习惯把这件事类比成“唤醒”:

  • 设备空闲:ASPM说“睡吧睡吧”,链路进入L1,电都省了。
  • 数据来了:设备被唤醒,链路重新建立连接。
  • 重新训练:两端重新协商速率和宽度。

关键在于,重新协商时,速率不一定能回到Gen3/Gen4。为什么?

我曾经踩过一个坑:一块网卡在低负载时频繁掉包。查了一圈,发现是ASPM让链路频繁进入L1,每次唤醒重训时,对端Root Complex的PLL锁相环状态不稳定,导致链路只能降到Gen1速率通信。虽然不是每次都会降,但一旦降了,带宽就只剩原来的十分之一。

所以,链路速率协商不是板上钉钉的事。它受信号质量、功耗预算、甚至温度影响。ASPM只是允许链路降速,但是否真的降速,由两端实际的硬件能力决定。

下面这张流程图帮你理清ASPM开启后,链路的状态机演变:

ASPM开启后PCIe链路状态机与速率协商流程 L0 (全速运行) Gen3/Gen4 正常数据 空闲检测 无数据流量,超时判定 L0s (浅睡眠) TX/RX 独立关闭 L1 (深睡眠) 链路时钟/参考时钟关闭 速率降级重训 可能降至Gen1/Gen2 L0 (恢复全速) 重训成功,回到Gen3 速率协商的关键点 1. L0s唤醒快(几ns),通常不降速;L1唤醒慢(几us),重训时可能降速 2. 降速与否由LTSSM、电气环境、双方能力共同决定 3. 一次降速不代表永久降速,下次重训可能回到Gen3
避坑指南:我看过很多工程师拿着lspci输出大喊“为什么只有Gen1!”。实际可能只是设备刚退出L1状态,链路还没协商到最优速率。等几秒钟再查,可能就恢复正常了。别慌。

2.2 电源状态切换:L0/L0s/L1 到底差多少?

ASPM定义了两种低功耗状态:L0s和L1。它们的目标都是省电,但“省电”和“性能”向来是跷跷板的两头。

说白了,L0s是“浅睡眠”,L1是“深度睡眠”。

咱们直接看一个对比表格,一目了然:

状态 描述 唤醒延迟 功耗节省 对带宽的影响
L0 全速运行,数据随时传输 N/A 0%(基线) 全带宽,无损失
L0s TX或RX方向独立关闭 ~几十ns 低(约20-40%) 几乎无感,适合突发流量
L1 链路时钟、参考时钟都停 几us到几十us 高(可达80-90%) 明显,小包场景下性能下降

2.3 对带宽的真实影响:别被数据表骗了

讲个真实的项目经历。有一次,我在优化一块NVMe SSD的性能。数据表上写支持Gen4 x4,理论带宽8GB/s。但实际跑4K随机读写,IOPS死活上不去。

我用perf和lspci -vvv抓了一下,发现ASPM打开了L1状态。每次IO请求间隔超过5us,链路就进入L1。下一个IO来时,光唤醒就要花几十us。你想想看,4K随机读,延迟从10us涨到上百us,IOPS直接砍半。

这里有一个计算思路:

  • L0状态下:4K读延时 ~10us,每秒可完成10万次IO。
  • 开了L1 ASPM后:唤醒时间 ~30us,传输时间 ~10us,总延时变成40us。每秒只能完成2.5万次IO。
这就是ASPM对带宽的隐形影响。它不是让链路跑不快,而是让链路跑不起来。

注意:像NVMe SSD这种延迟敏感型设备,开启ASPM的L1状态后,性能降幅可能高达50%以上。我个人建议,如果是服务器场景,数据库或高频交易场景,最好关掉ASPM的L1,只保留L0s,甚至全关。至于笔记本或移动设备,省电优先,那就得权衡了。

2.4 总结:预期行为是你排查的“标尺”

这一章我们梳理了ASPM开启后的正常表现。我归纳一下核心点:

  1. 链路速率协商是动态的:链路可以在L0→L0s/L1→L0的切换过程中,主动降速到Gen1/Gen2,这是预期行为,但不一定每次都会发生。
  2. 电源状态切换有代价:L0s几乎无感,L1的唤醒延迟会显著影响小包/低延时场景的带宽。
  3. 降速不等于故障:要结合实际的流量模型(连续大包 vs 间歇小包)来判断。如果间歇小包场景下速率降到Gen1,可能只是省电策略在起作用。

嗯,这里要注意:很多工程师用lspci看到链路速率掉到Gen1,就急着去调设备树或者BIOS设置。我建议你先用perf stat抓一下链路的实际利用率。如果利用率很低,那降速反而是对的。

这一章的内容,就是你后面排查所有ASPM相关问题的基线。记住这个基线,我们才能知道自己面对的究竟是“预期行为”还是“异常故障”。