尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

PCIe Switch实用指南:从端口拆分到错误计数与链路调试

PCIe Switch实用指南:从端口拆分到错误计数与链路调试 1. 别把PCIe Switch当普通桥接芯片用先想清楚它到底解决什么问题我最早接触PCI Switching Solutions的时候第一反应也是“这不就是个转接卡/桥接芯片吗”。实际深入做下来才发现PCIe SwitchPCIe交换芯片跟传统意义上的PCI桥完全不是一回事。先明确一个概念PCIe Switch不是一个简单的中转站它本质上是一个多端口、可路由的包交换网络。你可以把它理解成PCIe世界里的“路由器”而不是“网线直连”。它不只是在两根PCIe链路之间搬运数据而是在多个端口之间的任意两个端点Endpoint之间建立专用的、并行的数据通道。这意味着只要Switch内部的交换矩阵Fabric带宽足够多对端口可以同时全速通信互不干扰。那这个能力到底有什么用我从实际场景讲起。在服务器和数据中心里最典型的痛点就是PCIe lane信道数量不够用。CPU的PCIe通道数是固定的比如一颗主流服务器CPU通常提供64~128条PCIe 5.0/6.0 lane。你要接GPU、NVMe SSD、网卡、RAID卡、FPGA加速卡每条lane都是稀缺资源。一个PCIe x16的GPU就要占掉16条lane一块高端NVMe盘又要占4条CPU那点家底根本不够分。PCIe Switch就是来解决这个矛盾的。它挂在CPU的一个x16端口上然后向外部扩展出更多的PCIe端口把有限的CPU lane“复制”成更多可用的连接。这就像家里只有一个水龙头但你需要同时给十几块地浇水那就在主管道上接一个分水器分出十几个出水口。PCIe Switch就是这个分水器。关键区别在于这个分水器不是简单地一分多它内部的仲裁和交换逻辑足够聪明。每个端口收到的TLPTransaction Layer Packet事务层数据包都会被解析、查路由表、转发到目标端口这个过程完全由硬件完成延迟在百纳秒级到微秒级。所以当你在评估一个PCI Switching Solutions方案时第一件事不是看它的PCB长什么样而是先搞清楚三件事拓扑形态你是要对称的peer-to-peer通信比如GPU直连GPU还是非对称的fan-out一个CPU端口扩出多个设备端口带宽匹配Switch的上行带宽Upstream接CPU那侧必须大于等于所有下行端口Downstream接设备那侧的峰值带宽之和否则必然出现拥塞。协议细节你跑的是PCIe 4.0还是5.0是否要拆分Bifurcation是否要支持Non-Transparent BridgeNTB这些直接决定你选什么芯片、做什么配置。这些点如果没想清楚后面做出来轻则不达标重则直接翻车。2. 动手前必须吃透的PCIe Switch核心概念2.1 Transparent Bridge和Non-Transparent Bridge到底选哪个这两个术语是PCIe Switch选型的第一道分水岭。**Transparent Bridge透明桥TB**模式下CPU看到的Switch只是一个普通的PCIe bridge。它下面的所有设备都由同一个Root ComplexRC根复合体统一枚举和管理。软件的视角里这些设备仿佛直接挂在CPU的PCIe总线上地址映射、中断路由统统由BIOS/UEFI或操作系统自动处理。这种模式适合绝大多数“单主机扩展设备数量”的场景比如服务器里加一块PCIe Switch卡把1个x16口扩成4个x16口来接4块GPU。**Non-Transparent Bridge非透明桥NTB**就复杂了。它允许两个独立的Root Complex比如两颗CPU甚至两台物理服务器共享同一块PCIe Switch下的设备资源同时保持各自地址域的隔离。用白话讲TB模式下是一台主机管所有设备NTB模式下是两台主机“分地盘”可以互相访问对方的设备或内存区但对各自系统来说对面的东西只是一个“远程设备”。从我的实践来看不少初次接触的人会在这块犯迷糊拿NTB当TB用结果系统枚举阶段就因为地址冲突直接挂掉。或者反过来在必须用NTB做双主机互连比如双控存储阵列的场景里却选了不支持NTB的Switch芯片最后方案推倒重来。2.2 Bifurcation端口拆分与Lane分配的坑PCIe Switch的灵活性很大程度上来自lane的动态分配。但“灵活”也意味着“坑多”。以一颗支持PCIe 5.0 x16的Switch芯片为例它内部的物理端口可能被配置成1个x16端口2个x8端口4个x4端口1个x8加2个x4端口各种组合……这种拆分能力叫Bifurcation如果你用的是Intel平台一般叫PCIe Bifurcation在Switch芯片的语境里更多的叫Port Configuration或Lane Disable。我遇到过的最常见问题是硬件按x16画板但固件默认把所有端口配置成了x4导致链路训练后设备协商出来的带宽远低于预期。排查这类问题首先要确认Switch芯片的配置引脚Strapping Pin或配置寄存器然后把端口模式配成和PCB布线一致最后用lspci -vvv或PCIe Link Status寄存器核对实际协商的Lane数和速率。2.3 上游端口、下游端口与P2P路由PCIe Switch在逻辑上分为一个上游端口Upstream PortUSP和若干个下游端口Downstream PortDSP。所有指向CPU的流量走USP所有指向外设的流量走DSP。但注意这不是唯一的数据路径。PCIe Switch支持Peer-to-PeerP2P传输——两个DSP上的设备可以直接交换数据完全不经过上游CPU。P2P能力是PCIe Switch在加速场景里的核心价值。例如GPU直接读写NVMe SSD、两块网卡做点对点数据传输都可以绕过CPU节省主机内存带宽和CPU占用。我实测过一个基于PCIe 5.0 Switch的方案两块FPGA通过P2P互传数据延迟比经过CPU中转低了大约60%到70%。但是P2P的实现依赖Switch的Routing ID和地址转换表。每个下游设备都有一个Bus/Device/FunctionBDF编号Switch靠这个编号来决定把TLP从哪个端口转发出去。这块如果配置错误最常见的现象就是“设备能枚举但一跑P2P通信就挂死或者报URUnsupported Request完成包”。2.4 错误上报机制为什么你会看到“PCI Express Root Port”的错误日志关于错误上报这是很多服务器运维人员会半夜被叫起来的问题。Windows事件查看器里经常出现发生了已更正的硬件错误。 组件: PCI Express Root Port 错误源: Advanced Error Reporting (PCI Express)或者是Linux dmesg里刷出pcieport 0000:00:1c.0: AER: Corrected error received: 0000:00:1c.0 pcieport 0000:00:1c.0: PCIe Bus Error: severityCorrected, typePhysical Layer这些错误并不一定意味着硬件坏了。PCIe协议本来就有容错机制LLRLink Layer Retry链路层重传和物理层的纠错都能处理大部分瞬时错误。但你如果是在PCIe Switch方案里看到这类日志就要多留一个心眼因为Switch是整个链路的关键枢纽它自身如果产生了过多的Corrected Errors往往是链路信号完整性、参考时钟质量或供电噪声的前兆。热词里提到的“bad DLLP count”和“bad TLP count”这两个是PCIe链路层错误计数直接反映物理链路上的数据完整性问题。DLLPData Link Layer Packet是链路层维护链路状态用的包TLP是真正承载数据的包。如果这两个计数持续增加意味着链路底层在频繁出问题Switch和端点的收发器SerDes很可能已经在“挣扎”了。后面第三、第四节我会专门展开讲错误计数分析和排查方法。3. 实操案例基于PCIe Switch的NVMe存储扩展方案3.1 项目背景与需求拆解讲完概念我拿一个完整的项目来讲实操。之前接过一个需求一台双路服务器CPU原生PCIe通道已经被2张GPU和2张100G网卡占满客户还想再扩8块NVMe U.2 SSD做高性能存储池。算一下账8块NVMe SSD每块需要一个PCIe 4.0 x4的链路合计需要32条lane。但服务器剩余的PCIe插槽资源里能腾出来的只有一个x16插槽和一个x8插槽也就是总共24条lane而且位置分散。这时候如果直接用CPU的lane硬接lane数量不够而且插槽位置物理上也对不上。方案就是用一颗PCIe 4.0 Switch芯片来做扇出Fan-out从CPU的x16端口接到Switch的上游端口。Switch下游配置成8个x4端口8块NVMe。最关键的带宽需求8块NVMe盘的峰值带宽之和为8 x 7.5GB/sPCIe 4.0 x4单方向≈ 60GB/s而上游的x16端口在PCIe 4.0下单方向带宽约32GB/s。这里要泼一盆冷水如果8块盘同时满速写上游一定会成为瓶颈。但实际业务里存储访问不会永远全速而且我们有局部性原理——通常一部分盘在写一部分盘在读上行和下行带宽可以错峰复用。这个方案最终能落地的关键就是基于真实IO模型做带宽估算而不是拍脑袋。3.2 硬件设计要点时钟、耦合电容与PCB布线PCIe Switch方案的硬件设计和普通单板不一样。这里讲几个核心点参考时钟Refclk方案。PCIe有Common Refclk和Independent Refclk两种架构SRIS。在Switch方案里如果各下游端口的设备和Switch用的不是同一个时钟源必须考虑SRIS架构下的时钟容忍能力。最稳妥的做法是给Switch和所有端点提供同一个低抖动参考时钟源用时钟缓冲器Clock Buffer做扇出。这个环节如果偷懒后面链路训练经常会出现“协商速率掉档”的问题比如明明支持Gen4却只能协商到Gen3。AC耦合电容。PCIe链路要求每对差分信号串联AC耦合电容电容值通常在75nF~200nF之间。PCB布局时要保证这级电容尽量靠近发送端。常见低级错误是电容放反、容值选错或者差分对等长没有对齐结果高速信号反射严重。差分阻抗。PCIe的差分阻抗要求是85欧姆注意这不是普通的100欧姆以太网差分线。PCB叠层设计和走线宽度必须按85欧来算。很多第一次画PCIe板子的人习惯性用100欧阻抗做出来的链路眼图就是不合格的还会体现在错误计数上。Lane等长。同一个端口的8条lane之间走线长度差必须控制在5mil以内PCIe 5.0 Gen4时代相对宽松但越快越严。不同端口之间的等长可以放宽因为PCIe协议有弹性缓冲Elastic Buffer机制来吸收相位差但同一个端口的lane是全并行跑的歪太多直接训练失败。3.3 固件配置端口模式、链路速率和错误掩码硬件回来后固件是另一个主战场。PCIe Switch芯片通常通过I2C/SPI接口访问配置寄存器空间或者用芯片厂商提供的驱动工具来配置。关键的配置项包括端口模式把下游端口拆成8个x4还是4个x8取决于你的设备数量和带宽模型。链路速率强制Gen4还是自适应。调试阶段建议先固定到Gen3链路稳定后再切换到Gen4。直接上Gen4如果信号质量不行问题会被放大。错误掩码默认情况下Corrected Errors不会上报到系统日志。但可以配置成“记录到错误日志并继续运行”。这里要特别注意不要把Uncorrected Errors也掩掉否则系统遇到真正的硬件故障时毫无感知后续数据损坏了才追悔莫及。3.4 系统层的验证流程系统上电后按以下顺序验证端口枚举检查操作系统里确认所有8块NVMe盘都被正确识别。Linux下用lspci -tv查看树形结构确认每个设备出现在正确的Bus号下。链路协商速率确认对每个NVMe盘跑lspci -vvv查看LnkSta字段。确认速度显示为16.0 GT/sGen4、宽度为x4。顺序读写压测用fio做全盘顺序写和顺序读观察每块盘的实际带宽。如果带宽远低于标称值用lspci -vvv看是否有降速或者查Switch的端口统计寄存器看是否有大量重传。错误计数快照读取系统中PCIe错误计数。/sys/kernel/debug下的一些节点和NVMe的smart log里都会记录PCIe错误。记录初始值压测后再读一次对比增量。4. 热词里那些错误计数到底该怎么分析和定位4.1 Receiver Errors、Bad DLLP、Bad TLP的含义回到热词里“gpu的pci express error counters下的receiver errorsbad dllp countbad tlp count”这个高频问题。这几个都是PCIe物理层和链路层的错误指示器。Receiver Errors接收错误物理层SerDes收到的数据出现信号完整性错误。可能原因是信号反射、串扰、功耗噪声、参考时钟抖动过大或者链路本身太脏。Bad DLLP Count坏的数据链路层包计数DLLP是链路层维护信息包包含ACK/NAK、电源管理、流控等。如果收到CRC校验失败的DLLP这个计数就会增加。这意味着链路已经不稳定到数据包层面的完整性都无法保证。Bad TLP Count坏的事务层包计数TLP是真正的数据包。Bad TLP意味着用户数据在传输过程中出现了CRC错误、格式错误需要重传。这三个计数出现的场景和严重程度不一样。如果只是偶尔有Corrected Errors属于PCIe正常的容错机制在工作不用太紧张。但如果Bad TLP Count或Bad DLLP Count持续增长甚至伴随Uncorrected Errors那基本可以断定链路存在问题严重时会导致设备重置或系统崩溃。4.2 排查链路错误的标准流程我的建议是按从简单到复杂的顺序排查第一步核对链路协商状态。先确认设备跑在预期速率和宽度上。如果设备本来就协商在降速状态错误计数再高都是“果”而不是“因”。先修“因”。第二步检查错误发生的时间模式。看错误日志是持续刷还是间歇性出现。如果只在设备高负载时出现十有八九是供电或噪声问题高负载时电流增大PCB上IR drop加剧电源纹波变大影响SerDes的电压裕量。第三步排除线缆和连接器问题。如果链路经过了线缆或背板连接器用质量更好的线缆或者重新插拔测试。连接器接触不良导致的错误性能特征和信号完整性问题是不同的通常错误是突发的且没有规律。第四步检查参考时钟和PCB。这一步是Switch方案里最容易出问题的。用示波器测参考时钟的抖动用眼图仪看高速信号的眼图是否合规。如果设备在信号质量差的链路上还能工作多半是PCIe自带的均衡Equalization在起作用但这类方案通常是“能用但不稳”负载一上来就露馅。第五步用寄存器数据辅助定位。PCIe规范的AERAdvanced Error Reporting能力结构里有很多细分的错误状态位。除了Corrected和Uncorrected的Total Error Status还有专门的Header Log寄存器记录错误发生时TLP的头部信息。分析头部的Requestor ID和Tag可以精确定位是哪个设备发起的传输出错了。4.3 哪些错误不用管哪些错误绝不能忽视我见过太多人一看到Corrected error received就紧张得不行。实际上PCIe链路在正常运行中都会偶发Corrected Errors尤其是服务器长期运行、环境温度升高、电源波动时更是如此。这类错误由协议层自动重传机制修复对用户无感日志里记录一下而已。我的建议是设定一个阈值Corrected Errors在短时间内超过每秒几十次需要关注。Uncorrected Non-Fatal Errors系统还能继续跑但必须尽快处理。Uncorrected Fatal Errors直接导致设备或总线失效这是最严重的情况。真正危险的信号是“Corrected Errors逐渐变成Uncorrected Errors”或者“错误导致设备直接从总线上消失”。前者说明硬件问题在恶化后者说明系统已经无力回天。5. 两种常见场景的落地差异GPU服务器和NVMe存储5.1 GPU直连为什么Peer-to-Peer这么重要在GPU服务器的场景里PCIe Switch通常不只是做风扇扩展更重要的是做GPU之间的P2P通信。CUDA编程里常用的GPUDirect RDMA和NVLINK的替代方案很多就走P2P模式。这里有一个硬件层面的关键区别。如果把GPU直接挂在CPU Root Complex下GPU通信必须走CPU消耗系统内存带宽。而在GPU通过PCIe Switch互连的结构里一个GPU可以直接用P2P TLP访问另一个GPU的显存走Switch内部交换矩阵不需要把数据先拷到系统内存。实测里PCIe 5.0 x16的Switch内部P2P带宽能跑到每个方向接近64GB/s单向虽然比不上NVLink那么夸张但相比走系统内存的传统路径优势仍然很大。要注意的是P2P路径的TLP包头里地址和BDF的映射关系必须正确。如果系统里有多颗CPU、多个SwitchNUMA拓扑和数据路径就变得很复杂经常出现P2P请求被发送到了错误的PCI域导致UR错误。5.2 NVMe存储别让一个Switch成为所有盘的瓶颈NVMe存储扩展是PCIe Switch最常见的落地方向但也是最容易“翻车”的方向。原因很简单很多人只算了“带宽够不够”没算“延迟有多高”。PCIe Switch会增加几微秒的时延。对NVMe来说原本直连CPU时的延迟在10微秒左右经过Switch后可能变成12~15微秒。纯顺序读写的场景无感但随机小IO4K场景下延迟增加会直接影响IOPS的峰值表现。要控制这个影响我的经验是优先选择支持Cut-Through转发模式的Switch而不是Store-and-Forward。前者在收到TLP的头几个字节后就开始转发延迟更低。后者需要整个包收完再转发延迟高不少。中断方面MSI-X中断和多队列要配置好否则中断处理变化会让NVMe驱动产生额外开销。掉电保护Power Loss ProtectionPLP在Switch方案里更容易被忽略。NVMe盘自身的PLP只能保护盘内缓存如果数据路径经过Switch掉电时Switch掉电会让正在传输的TLP直接丢包可能造成文件系统损坏。在存储产品里建议给Switch和存储背板加独立的掉电保持电路。6. pcie\VEN_8086DEV_9DA8这类设备ID问题怎么看才不慌热词里还有一个非常典型的条目PCI\VEN_8086DEV_9DA8SUBSYS_17A11043REV_30这串信息在Windows设备管理器里经常以“PCI简单通讯设备”或“未知设备”的面貌出现。很多人的第一反应是“驱动没装好”然后满世界找驱动。其实这未必是驱动问题。VEN_8086表示Vendor ID是0x8086这是Intel的设备DEV_9DA8是Device ID查Intel的PCI ID表这是Intel某代芯片组的PCIe Root Port具体来说通常对应第11代或第12代酷睿处理器PCH内置的PCIe控制器。SUBSYS的值是主板厂商的子系统IDREV_30是硅片步进版本。关键是PCIe Root Port在设备管理器里有时没有对应的功能驱动系统会统一识别为“PCI简单通讯设备”。如果PCIe链路下面挂了正常的NVMe、网卡、GPU它们都能正常工作那么根本不需要为这个Root Port特意装驱动。那什么时候需要关注如果你发现这个Root Port下面挂的设备消失、出现黄色感叹号或者伴随错误日志这时候才需要查具体原因。常见的原因包括BIOS里PCIe端口被禁用先检查主板的BIOS设置把对应端口的PCIe功能打开。设备被安全移除但系统没识别回来尝试关机彻底断电再重新开机。端口的链路训练失败这类问题会在系统日志里有对应的PCIe错误记录参考上面的错误分析流程排查。7. 技嘉主板“PCI数据捕获驱动”是干什么的热词里还有一个“技嘉主板PCI数据捕获驱动”这也是一个容易被误读的条目。很多用户装上这个驱动后发现设备管理器里多了一个奇怪设备担心是不是“后门程序”。其实这是技嘉主板在BIOS层面提供的一个系统管理功能驱动和PCIe的总线枚举有关。它允许操作系统获取一些内存和PCI总线信息采集能力用于硬件监控、功耗管理和超频面板的实时数据展示。它本身不是一个常驻后台的“捕获工具”而不是在网络层面做数据抓包所以没有安全风险。如果这个驱动导致系统蓝屏或睡眠唤醒异常可以直接卸载。它和PCIe Switch解决方案没有任何直接的性能关系卸载后GPU、NVMe这些设备的性能不受影响。8. 调试PCIe Switch方案时我最常用的几板斧最后分享几个我在实际调试中反复用到的技巧。第一板斧用PCIe Link Training错误状态码定位训练失败原因。PCIe协议定义了一组LTSSMLink Training and Status State Machine状态。当链路无法训练成功时从设备的Link Status寄存器里读到的状态码会告诉你卡在哪个阶段。比如0x00表示Detect状态物理连接可能都没建立检查线缆或焊接。0x04表示Configuration状态通常是Lane翻转、极性翻转或者Bifurcation配置不对。0x08表示L0状态链路已经起来但速率可能不对。第二板斧跑数据的同时抓Transact Layer的错误日志。光看链路状态不够要端到端验证。用dma测试工具或者简单的pio读写慢速连续跑几小时看错误计数有没有爬升。如果没有专门的PCIe分析仪至少用Linux的AER日志和设备的smart log交叉验证。第三板斧控制变量去排查信号完整性问题。如果某条链路错误频繁把它的速率降到Gen3甚至Gen2看错误是否消失。如果降速后错误明显减少说明信号裕量不足。这时要排查的就是PCB设计、参考时钟质量和连接器而不是固件。第四板斧关注散热。PCIe Switch芯片是一个真正的功耗大户一颗PCIe 5.0 x16的Switch芯片功耗可能在15W到30W之间。如果散热不够芯片温度过高会触发内部的降频保护表现就是链路速率掉档或者错误计数上升。我在一个方案里遇到过Switch过热导致P2P带宽从40GB/s掉到10GB/s的情况加了散热片和风道后恢复正常。这类问题在业务负载重的时候才会暴露很容易被误判为信号质量问题。做PCIe Switch方案这件事说复杂也复杂说简单也简单。复杂的是它涉及信号完整性、链路层协议、系统软件和多设备协同任何一个环节出问题最后的症状都可归结为“设备不见了”或“性能不达标”排查起来很有挑战。简单的是只要按层次去拆解——从物理信号质量到链路训练再到事务层错误——每个问题都能找到明确的归因方向。我自己的经验是千万别在看到一个错误计数的时候就急着改硬件先静下心把日志完整读一遍很多问题的线索已经写在里面了。
返回列表