2026/9/27 2:22:42

PCIe 链路是怎么练成的:速率、宽度、均衡与故障判断

PCIe 链路是怎么练成的:速率、宽度、均衡与故障判断 目录1. 分层不要把所有现象都算到 Lane 上2. Lane 上实际传的是什么3. 时钟、复位和供电4. 链路训练状态机DetectPollingConfiguration宽度、反转和极性Recovery升速和重训练5. 均衡在补偿什么四相分别由谁主导均衡结果写在哪6. L0 之后的两层7. 低功耗和几种复位8. 配置空间怎么读9. 和 Lane 无关、但会影响性能的配置10. 一份正常 Gen4 x4 里哪些异常才算数11. 按场景排查12. 结论一条 PCIe Link 最终显示成什么样是电气检测、低速训练、宽度编号、升速、均衡和两层协议栈依次完成的结果。Lane 数只是其中一项。下面按信号、状态机、均衡、进入 L0 之后的协议以及常见故障场景说明这些读数分别代表什么。1. 分层不要把所有现象都算到 Lane 上从金手指到 NVMe 命令经过五层层负责什么失败时通常看到供电、时钟、复位3.3 V、100 MHz 参考时钟、PERST#配置空间完全不出现电气 / 逻辑物理层差分信号、编码、Lane、速率、均衡降速、降宽、RxErr、链路反复训练数据链路层序列号、LCRC、ACK/NAK、重放、流控信用BadTLP、BadDLLP、Replay Timeout事务层Memory Read/Write、CompletionCompletion Timeout、Unsupported RequestNVMe队列、门铃、PRP/SGL、命名空间I/O timeout、控制器复位LnkSta可能仍正常带宽不够时先看LnkSta是不是仍为满速满宽。是就离开 Lane 这一层去查 Max Payload、Tag、队列、温度和盘内通道。不是才沿训练和物理连接往下查。2. Lane 上实际传的是什么一条 Lane 是两对差分线收发同时进行所以是全双工。x4 是四条这样的 Lane 组成一条 Link不是把一条 Lane 分成四股。接收端看的是正负两线的电压差。两边同时抬高或降低的共模噪声会被抵消。发送端串联交流耦合电容只传递跳变不传递直流电平。对端接有终端时Detect 阶段的充电特征与开路不同开路就被当成“这条 Lane 没有设备”。速率的单位是 GT/s表示每秒原始比特不是每秒字节。编码开销如下代速率编码效率Gen12.5 GT/s8b/10b80%Gen25 GT/s8b/10b80%Gen38 GT/s128b/130b约 98.5%Gen416 GT/s128b/130b约 98.5%Gen532 GT/s128b/130b约 98.5%单向理论带宽GT/s × Lane 数 × 编码效率 / 8Gen4 x4 约为 7.88 GB/s十进制约 7.34 GiB/s。这是物理层数据速率。门铃、命令、完成项、短包和流控都会再占掉一部分所以顺序读写略低于此仍可能完全正常。Gen1/2 用 8b/10b每个字节变成 10 比特并用极性失衡约束帮助接收端保持锁定。Gen3 起改用 128b/130b128 比特数据加 2 比特同步头。同步头区分数据块和有序集不再靠 8b/10b 那种逗号符号。链路上除了事务包还有只在物理层使用的有序集有序集作用TS1 / TS2训练。携带链路号、Lane 号、速率、FTS 数量、均衡阶段和系数SKP补偿两端时钟的微小频差由弹性缓冲吸收EIOS通知对端“我将进入电气空闲”EIEOS从电气空闲返回时给接收端一个容易锁定的固定图案FTS从很浅的 L0s 恢复时帮助接收端重新锁定SDS训练结束、正式数据流开始前的起始标记SKP 不是用户数据。独立且带扩频的参考时钟频差更大需要更密的 SKP 和更深的弹性缓冲。缓冲溢出或抽空会记成接收错误。3. 时钟、复位和供电差分 Lane 之外还有三样东西决定训练能不能开始。参考时钟通常是 100 MHz有三种架构共同时钟主板把同一路时钟送给 Root Port 和 SSD多数还带扩频。两端的CommClk都应置位再重训练退出低功耗状态的时序才匹配。独立时钟、不扩频SRNS两端各有时钟源频差较小。独立时钟、各自扩频SRIS频差最大对弹性缓冲要求最高。SlotClk表示设备使用插槽提供的时钟。它和CommClk同时出现才是典型的共同时钟。两个都是减号表示独立时钟链路已经稳定时不要为了把这两个比特“改成加号”去重训练。时钟架构判断错了余量会变差。PERST#有效期间设备停在确定状态不会开始 Detect。释放顺序应是电源和时钟先稳定再释放复位。转接卡把PERST#一直拉住软件侧就是设备消失没有任何LnkSta。3.3 V跌落不一定造成永久掉速。它可能只在上电瞬间制造一次接收错误也可能在负载电流升高后让设备掉线。M.2 还有功耗档。盘的峰值超过插槽供给时表现可以很像链路闪断但重新枚举后的速率和宽度仍是满的。4. 链路训练状态机上电后的主路径电源、参考时钟稳定 │ PERST# 释放 │ Detect 逐 Lane 判断有没有终端 │ Polling 2.5 GT/s 上交换 TS1/TS2完成位锁定和块锁定 │ Configuration 协商宽度、Lane 编号、极性 │ L0 2.5 GT/s 先建立一条可用的低速链路 │ Recovery 按能力和目标速率升速 │ Equalization 8 GT/s 及以上才有 │ L0 目标速率 配置空间稳定可读无论设备最终是 Gen3、Gen4 还是 Gen5第一段通信一定发生在 2.5 GT/s。最终显示 16 GT/s只说明后面的升速和均衡成功了。Detect发送端先处于电气空闲再发出接收端检测脉冲通过交流耦合电容观察对端终端。有终端才进入后续训练。x4 里只有两条能检测到后面最多协商成 x2。接触不良、转接卡断线、插槽本身没布线在这里就被当成 Lane 不存在而不是“训练失败”。PollingPolling.Active 连续发送 TS1。双方都收到对方后进入 Polling.Configuration用 TS2 确认然后离开 Polling。这一阶段完成位锁定128b/130b 下还要完成块锁定。锁定失败就没有机会谈宽度。Polling 里还有 Compliance 子状态用于一致性测试夹具。普通 SSD 正常启动不会停在那里。Configuration宽度、反转和极性Linkwidth.Start / Accept两端在 TS 里宣告支持的宽度。下游端口根据实际检测到的 Lane 提议上游端口接受一个共同支持的合法宽度。合法值是 x1、x2、x4、x8、x12、x16、x32。消费级 SSD 一般最高 x4。Lanenum.Wait / Accept给留下的 Lane 分配逻辑编号并识别整组反转。Complete / IdleTS2 确认数据链路层准备进入活动状态随后到达 2.5 GT/s 的 L0。两种看起来像布线错误、实际合法的情况极性翻转同一对差分线的 P/N 接反。训练图案可以发现接收端内部交换不降宽。Lane 反转下游 Lane0 接到上游最后一条 Lane。状态机整组重编号x4 仍然是 x4。宽度变小说明有 Lane 没检测到或者检测到了但中途失去锁定只能用剩余 Lane 重新接受一个更窄的宽度。它不是极性问题。服务器 CPU 还可以做Bifurcation。一个 x16 控制器在复位前被拆成 x8x8 或 x4x4x4x4每段是独立 Link各自训练。SSD 不能在训练中把相邻两段合成一条 x8。BIOS 拆分方式和背板布线不一致时典型现象是降宽或者部分盘完全不出现。术语方向要固定下游端口靠近主机是 CPU Root Port 或 Switch 的下行口。上游端口靠近设备SSD 端点上的 PCIe 口就是上游端口。“主机发往 SSD”是下游发送、上游接收。“SSD 发往主机”相反。后面的均衡和报错方向都按这个区分。Recovery升速和重训练低速 L0 建立后如果LnkCap支持更高速率而且LnkCtl2的 Target Link Speed 也允许链路进入 RecoveryRcvrLock重新锁定并用 TS 协商目标速率。Speed发送端进入电气空闲两端切换时钟和速率再用 EIEOS 帮助对方重新锁定。目标不低于 8 GT/s 时进入Equalization。RcvrCfg / Idle确认新速率可用返回 L0。8 GT/s 失败通常退回 5 或 2.5 GT/s16 GT/s 失败可以停在 8 GT/s。所以“能力是 Gen4实际是 Gen3”有两种完全不同的原因目标速率根本没允许 16 GT/s或者允许了但这一代的均衡没通过。运行中的误码、对端要求、改宽度或再切速也会从 L0 进入 Recovery。短暂经过是正常机制。反复进入并且回不到原来的速率和宽度才是不稳定。5. 均衡在补偿什么到 8 GT/s 以后过孔、连接器、长走线和背板会明显削弱高频。接收端眼图闭上后单靠加大摆幅没有用因为高频和低频一起被通道改变了。发送端用三游标均衡预游标提前改变边沿补偿尚未到达的码间干扰。主游标当前比特的主要能量。后游标削弱拖尾也就是去加重。若干合法组合被定义成预设P0–P10。预设只是起点随后还可以按单个游标增减这叫系数调整。主游标与前后游标要满足幅度和比例限制不能任意加大。接收端再做两类处理CTLE是模拟高频提升能把眼图张开但也会放大噪声。DFE用已经判决的前几个比特估计拖尾从当前比特里减掉。它不按 CTLE 那种方式放大噪声但判决错了会把错误往后传。参数取决于这块板的通道没有一组可以写死的最优值。每次升到 8、16 或 32 GT/s都要重新做。四相分别由谁主导阶段实际动作优化方向Phase 0下游端口按预设发送。上游端口只调自己的接收端先可靠识别 TS1主机 → SSD初步接收恢复Phase 1交换预设上游端口也开始按预设发送。目标是双向都能稳定接收训练序列还不追求最佳眼图双向先达到“能通信”Phase 2下游端口要求上游端口调整发送端SSD → 主机Phase 3上游端口要求下游端口调整发送端主机 → SSDPhase 2 和 Phase 3 的主从关系不能记反。主机收不好 SSD 的数据对应 Phase 2SSD 收不好主机的数据对应 Phase 3。TS1 里的 EC 字段用00、01、10、11表示当前阶段。任一阶段不能维持可靠的训练通信这一代速率失败链路退回较低速率。路径上还可以有Retimer。它含时钟恢复和重新发送把一条长通道拆成两段分别均衡。协议能检测到一个或两个 Retimer。Redriver 只做模拟放大训练状态不会把它报告成 Retimer。能力位只说明“我能报告”状态位才说明“这次检测到了”。没有 Retimer 不是故障长背板本应有 Retimer 却没有Gen4 失败、Gen3 成功才是典型现象。均衡结果写在哪LnkSta2的 Equalization Complete 和 Phase1/2/3记录的是8 GT/s那一次不是 16 GT/s。16 GT/s 的对应位在 Physical Layer 16.0 GT/s Statuslspci里通常是Phy16Sta一类字段32 GT/s 还有另一组。因此链路当前是 16 GT/s只看LnkSta2全成功只能证明 8 GT/s 曾经成功。16 GT/s 是否走完要看Phy16Sta的 EquComplete 和 Phase1/2/3。这些位表示最近一次结果停在 L0 后不会自动清除。同时没有 Link Equalization Request才表示硬件没有请求软件再安排一次均衡。6. L0 之后的两层物理层进入 L0只说明比特和块已经稳定。数据链路层给每个事务包加序列号和 LCRC。对端用 ACK 或 NAK DLLP 回应。NAK、LCRC 错误或重放计时器到期发送端从重放缓冲重传。偶发误码通常停在这一层表现为可纠正错误。重放次数滚翻或重放计时器超时说明误码已经连续到影响传输。事务层使用信用流控。转发、非转发和完成这三类Header 与 Data 信用分开。信用暂时耗尽时链路速率不变吞吐会停。信用用完却不再更新是流控协议错误不是降速也不会把 x4 变成 x1。NVMe 使用其中几种事务主机写门铃、写寄存器主机发出的小 Memory Write。主机读寄存器Memory Read 加 Completion。SSD 读取命令、PRP/SGL以及主机写盘时读取主机内存SSD 主动发出 Memory Read。SSD 把读出的数据写回主机SSD 发出 Memory Write。完成队列项也是 SSD 写到主机内存。所以“盘读主机内存”才受 SSD 作为请求方的 Tag 数量限制“盘把数据写给主机”不受这个数量限制。7. 低功耗和几种复位ASPM 是运行中的链路省电不是系统睡眠本身L0s很浅方向可以单独进入。退出要靠 FTS。FTS 数量不够接收端就锁不回。现在的 SSD 很多不支持它。L1双向都进入电气空闲恢复更慢。L1.1 / L1.2进一步关闭共模电压或时钟依赖CLKREQ#。退出异常时表现为随机超时或掉盘。LnkCap写着 ASPM not supported同时LnkCtl是 Disabled就不要从 L1 开始排查。几种复位的影响不同复位链路是否重新训练速率宽度是否可能变化PERST#一定会重新协商Hot Reset会离开 L0 再回来会重新协商Function Level Reset重置 NVMe 功能通常不变D3hot / 系统睡眠后恢复可能重新训练可能停在更低速率故障前后各读一次LnkSta。没变优先查控制器、固件和供电变了优先查训练、时钟和信道。8. 配置空间怎么读设备出现在lspci里只说明它曾经到达 L0。判断当前链路看两端的这些字段字段含义LnkCap硬件上限最高速率、最大宽度、ASPMLnkCap2支持的速率向量以及是否支持 Retimer 报告LnkCtl2软件允许尝试的目标速率。低于能力时不会去练更高代LnkSta当前速率和宽度。(ok)表示达到该端能力downgraded才是降级LnkSta28 GT/s 均衡结果、均衡请求、Retimer 是否检测到Phy16Sta16 GT/s 均衡结果不能用LnkSta2代替LaneErrStat哪一条 Lane 的接收端记过错误UESta/CESta不可纠正错误和可纠正错误都是粘滞位端点上一些减号没有诊断意义TrErr-是早期规范遗留位现在固定为 0。Train-只给下游端口表示“正在训练”。DLActive-只由下游端口报告数据链路层活动。端点即使完全正常也是 0。Surprise-属于下游端口的热插拔状态。能读到配置空间并且nvme已绑定本身就说明链路当前可访问。不要用端点的DLActive-判断断链。要看这个状态去读上游端口。错误有方向。SSD 的RxErr只代表主机发往 SSD 的方向主机收 SSD 的错误记在 Root Port 或 Switch 下行口。只看盘会漏掉一半信道。CEMsk某位为减只说明这种错误没有被屏蔽。DevCtl的CorrErr-则表示设备不被允许向上游发送可纠正错误消息。配置空间里可以有加号内核日志却是空的。9. 和 Lane 无关、但会影响性能的配置Max Payload是一个事务包最多携带的数据。路径上每一跳取最小值。能力 512、实际启用 256通常是上游某跳只保证 256。它降低一点包效率不改变LnkSta。不要用setpci把它改大。Max Read Request是请求方希望一次读多少。完成包仍按 Max Payload 拆开。它不要求整条路径相同也不代表链路宽度。Tag是 SSD 作为请求方时未完成的非转发事务数量。5-bit 大约 32 个8-bit 扩展到 256 个。直连 CPU、往返时间不到 1 µs 时Gen4 x4 需要同时在途的数据大约只有几 KB 到十来 KB32 个 Tag 通常够用。中间经过多层 Switch、往返到数微秒时32 个 Tag 乘以较小的读请求长度才可能限制“SSD 读主机内存”的吞吐。Tag 不够不会把训练结果变成 x2。10. 一份正常 Gen4 x4 里哪些异常才算数设 NVMe 端点是01:00.0驱动已绑定读数是LnkCap16 GT/s、x4、不支持 ASPM。LnkCtl2目标就是 16 GT/s。LnkSta16GT/s (ok), Width x4 (ok)。LnkSta28 GT/s 四相成功无均衡请求。Phy16Sta16 GT/s 四相也成功无均衡请求。LaneErrStat为 0UESta全未置位。SlotClk-、CommClk-独立参考时钟。Max Payload 能力 512、启用 256。扩展 Tag 未启用。这表示当前就是满速满宽。单向上限约 7.88 GB/s。顺序带宽明显低于此不再查 Lane。独立时钟、端点上的DLActive-、没有 Retimer、256 字节 Payload都不能单独解释成降速。若唯一异常是DevSta: CorrErr CESta: RxErr BadTLP- BadDLLP- Rollover- Timeout-它表示 SSD 接收端曾经见到一次物理层接收错误。旁边没有坏 TLP、坏 DLLP 和重放超时不可纠正错误也为空所以数据链路层没有进入连续重放。可纠正状态是粘滞的上电、插拔或一次电源抖动都会留下这个加号。它还不能证明盘坏或槽坏。下一步是看反方向清除后复测。清除是对 AER 状态位写 1不是改速率lspci -PP -s 01:00.0 lspci -tv dmesg -T | grep -iE aer|pcie|nvme|01:00.0 setpci -s 01:00.0 ECAP_AER0x10.L0xffffffff # 对上游端口的 AER 不可纠正/可纠正状态也做同样的清除 # 再做一段实际读写 lspci -s 01:00.0 -vv | grep -E LnkSta|LnkSta2|Phy16|CESta|UESta|LaneErr同时读lspci -PP给出的上游端口。清除后不再增加可以忽略。空闲也快速增加或同时出现BadDLLP、Replay Timeout、Completion Timeout再查金手指、转接卡、背板和供电。高负载下偶发而两端始终是16GT/s (ok), Width x4 (ok)只说明余量一般。生产环境不要用setpci修改目标速率、Max Payload 或 ASPM。11. 按场景排查速度下降宽度仍是 x4。先看两端LnkCtl2。目标被限制在 8 GT/s就去查 BIOS 和平台而不是盘。目标已是 16 GT/s却停在 8 GT/s再看Phy16Sta停在哪一相。长背板、延长线、无 Retimer 的转接卡是这一类的常见原因。锁回 Gen3 后错误消失问题在信道余量。宽度下降速度仍高。优先查物理连接和拓扑金手指、M.2 座、转接卡断 Lane、插槽只布了 x2、相邻插槽共用 Lane、Bifurcation 与背板不一致。极性翻转和 Lane 反转不会造成降宽。换到已知按 x4 布线的直连槽后恢复就不是 SSD 端口能力的问题。设备完全不出现。没有配置空间可读。查 3.3 V、参考时钟、PERST#、BIOS 是否关闭插槽以及转接板键位。这是 Detect 之前或 Detect 失败不是LnkSta降级。运行中掉盘。温度节流时速率和宽度通常不变。链路闪断则上游端口会出现链路下降或 Surprise DownNVMe 同时报超时或控制器复位。支持 ASPM 的设备可以把 ASPM 临时关闭做对比能力里写着不支持就不要从这里开始。还要区分功耗不足掉线后重新枚举仍是满速满宽更像供电或复位不像均衡。只在一个方向报错。SSD 只有RxErr上游端口干净查主机发往 SSD 的发送端、连接器和 SSD 接收端。上游端口有接收错误SSD 干净查反方向也就是均衡 Phase 2 优化的那一路。某一位在LaneErrStat里反复置位查对应 Lane 的接触或走线而不是整条链路降速。可纠正错误变成不可纠正错误。BadTLP或BadDLLP开始伴随 Replay Timeout、Replay Rollover说明重放已经救不回来。再出现 Completion Timeout 或 Data Link Protocol ErrorNVMe 命令会失败。此时先保留两端lspci和内核日志再复位只重启机器会把粘滞位清掉。睡眠或热复位后停在 Gen1。看目标速率有没有被软件改低以及参考时钟是否在恢复时晚于PERST#。这是重新训练没有升速不是 NAND 变慢。性能低但两端已经是 Gen4 x4。按这个顺序排除温度和电源状态是否降频固件是否在稳态而不是 SLC cache 阶段。IO 大小、队列深度、线程和测试区间是否足够大。盘接在 CPU 直连 Lane还是接在芯片组后面。芯片组上行和多个设备共享带宽。Max Payload 是否异常地只有 128 字节。256 字节很少单独造成数量级下降。只有跨 Switch、延迟明显偏大时才评估 32 个 Tag。最后才看 NVMe 的队列数、MDTS、LBA 格式和主机调度器。一个槽正常、另一个槽降级。用同一块盘交换。问题跟着槽走查布线、Bifurcation 和转接卡问题跟着盘走再查盘的金手指和固件。不要同时更换盘、线和 BIOS否则无法归因。12. 结论Lane 是一条全双工差分通道Link 是若干 Lane 在同一速率下训练出来的整条连接。训练先在 2.5 GT/s 完成检测、锁定、宽度和编号进入 L0 后再升速8 GT/s 及以上还要按四相均衡。Phase 2 优化 SSD 到主机Phase 3 优化主机到 SSD。LnkSta才是当前速率和宽度LnkSta2的均衡位属于 8 GT/s16 GT/s 要另看Phy16Sta。端点上的DLActive、训练位和独立参考时钟不能单独当成故障。NAND 通道、Tag 和 Max Payload 影响性能不改变已经完成的训练结果。一个孤立且能清除的RxErr只是一次粘滞记录它与降速、降宽、重放超时或对端错误同时出现时才说明这条信道需要继续查。