2. PCIe Switch架构:内部结构、端口类型与路由机制

好,咱们今天聊聊PCIe Switch的内部架构。说实话,很多做DMA设计的工程师,对Switch的理解就停留在“一个能把多个设备连在一起的盒子”。但如果你真要做多主机拓扑,不了解Switch内部怎么工作的,迟早要踩坑。

我个人习惯把Switch看作一个“智能的报文分发中心”。它不像网桥那样简单转发,而是根据报文类型、目标地址,做出一系列决策。咱们从三个核心维度来拆解:内部结构、端口类型、路由机制。

2.1 Switch内部结构:到底长什么样?

先看一张我手绘的结构图,帮你建立直观印象。

PCIe Switch 内部结构示意图 UP (上行端口) DOWN (下行端口) NF (透明桥) 内部互联总线 / 交叉开关 (Internal Fabric / Crossbar) 路由表 (Routing Table) 仲裁器 (Arbiter) UP (可选) DOWN NF UP端口 DOWN端口 NF端口 路由表 仲裁器

Switch内部的核心,是那个内部互联总线(也叫Fabric)。它负责把各个端口连起来。每个端口背后,其实都是一个PCIe到PCIe桥(P2P Bridge)。嗯,这里要注意:Switch本质上就是一组P2P桥的集合体。

核心要点:Switch内部有一个路由表,它决定了报文从哪个端口进,从哪个端口出。仲裁器则负责处理多个端口同时请求时的优先级问题。

2.2 端口类型:UP、DOWN、NF

端口类型这事儿,我刚开始接触时也迷糊过。其实很简单,咱们按角色分:

2.2.1 UP端口(上行端口)

UP端口朝向Root Complex(RC)。说白了,就是离CPU更近的那个方向。在标准树形拓扑里,UP端口是Switch的“上级”。

  • 通常只有一个UP端口(但也有多UP的Switch,后面会讲)
  • UP端口处理发往RC的报文
  • 我记得有一次项目,客户非要把两个UP端口接到同一个RC上,结果配置了半天才发现,这需要特殊的非透明桥支持

2.2.2 DOWN端口(下行端口)

DOWN端口朝向Endpoint(EP)或者下一级Switch。它是“下级”接口。

  • 一个Switch可以有多个DOWN端口
  • DOWN端口负责管理挂在其下的设备
  • 我建议在设计多主机拓扑时,把关键设备挂在独立的DOWN端口上,避免带宽争抢

2.2.3 NF端口(非透明桥)

这个比较特殊。NF端口,说白了就是隔离域的边界。它不像普通端口那样直接转发报文,而是做地址转换。

实战技巧:NF端口常用于多主机隔离场景。比如两个主机共享一个存储设备,但彼此不想让对方看到自己的内存空间。NF端口会把一侧的地址空间映射到另一侧,实现“物理连通,逻辑隔离”。

我曾经在一个项目中,用NF端口实现了两个CPU域共享一个NVMe SSD。每个CPU看到的地址范围不同,但实际访问的是同一块物理存储。嗯,这个设计当时让客户觉得很神奇。

2.3 路由机制:报文怎么找到路?

PCIe Switch有三种路由方式。我按使用频率排序讲:

2.3.1 基于ID的路由(最常用)

每个PCIe设备都有一个唯一的Bus:Device:Function(BDF)编号。Switch根据这个ID来转发报文。

  • 配置读写(Configuration Read/Write)必须用ID路由
  • Switch内部维护一个ID路由表,记录每个BDF对应的端口
  • 我习惯把ID路由想象成“门牌号寻址”——你知道具体住址,直接找过去
// ID路由表示例(简化)
// Bus Number -> 对应端口
Bus 0x00 -> UP Port
Bus 0x01 -> DOWN Port 0
Bus 0x02 -> DOWN Port 1
Bus 0x03 -> NF Port

2.3.2 基于地址的路由

内存读写(Memory Read/Write)和IO读写走的是地址路由。Switch根据报文中的目标地址,查地址路由表决定转发端口。

  • 地址路由表本质上是基地址寄存器(BAR)的汇总
  • 每个端口都有对应的地址窗口
  • 你想想看,如果两个设备的地址窗口重叠了,那就会出大问题

避坑指南:我曾经遇到过一个案例,两个EP的BAR配置了重叠的地址范围,结果Switch不知道该把报文发给谁。系统直接挂死。所以,地址窗口必须互斥,这是铁律。

2.3.3 隐式路由

这个用得最少,但很重要。隐式路由用于消息报文(Message)。报文里不包含明确的地址或ID,而是通过消息类型来隐含目的地。

  • 典型例子:INTx中断消息、PME电源管理事件
  • Switch根据消息类型,决定是广播还是定向转发
  • 说实话,隐式路由在调试时最让人头疼,因为你看不到明确的目标地址

2.4 三种路由的对比

路由类型 适用报文 路由依据 典型场景
ID路由 配置读写 BDF编号 设备枚举、配置空间访问
地址路由 内存/IO读写 目标地址 DMA传输、数据搬运
隐式路由 消息报文 消息类型 中断、电源管理

2.5 多主机拓扑中的特殊考量

在多主机场景下,Switch的架构会变得更复杂。我简单提几个关键点:

  • 多UP端口:有些Switch支持多个UP端口,每个接一个主机。这时候需要非透明桥来隔离不同主机的地址域
  • 地址映射:NF端口会做地址转换,把一侧的物理地址映射到另一侧的虚拟地址空间
  • 死锁预防:多主机同时发起DMA时,可能形成循环依赖。Switch内部需要实现信用流控超时机制

个人经验:我做过一个4主机共享1个GPU的项目。每个主机都认为GPU是自己的,但实际上GPU的BAR被分成了4个区域,每个区域映射给一个主机。Switch的NF端口在这里起了关键作用——它做了4组地址转换。调试那会儿,我盯着逻辑分析仪看了整整三天,才把地址映射的bug找出来。

好了,关于Switch架构的核心内容就这些。记住:端口类型决定了角色,路由机制决定了路径,内部结构决定了性能。搞懂这三样,多主机拓扑的设计你就有了底气。

一句话总结:Switch不是简单的集线器,它是一个带路由表的智能交换中心。UP/DOWN/NF三种端口各司其职,ID/地址/隐式三种路由各管一摊。设计时,先想清楚你的拓扑需要哪种端口组合,再考虑路由怎么配。


公众号:蓝海资料掘金营,微信deep3321