PCIe 拓扑层次:Root Complex、Switch、Bridge 与 Device

基于双路 Sapphire Rapids (24 个 PCIe domain) + RTX 5090 实测。从 sysfs 出发,逐层解析 PCIe 拓扑的四个核心组件。


1. 四层模型

CPU Socket
  └── Root Complex (RC)
        ├── Root Port 0 → PCIe Bridge → Device (GPU)
        ├── Root Port 1 → Device (NVMe)
        ├── Root Port 2 → PCIe Switch → Device × N (NVMe阵列)
        └── Root Port 3 → Device (网卡)
组件 class code 职责
Root Complex (RC) CPU 内部,连接 CPU 与 PCIe 总线,每个 domain 对应一个 RC
Root Port 0x060400 RC 的下行端口,一个 domain 可有多个 Root Port
PCIe Switch 0x060400 (upstream) 扩展 PCIe 端口:1 个上行 + N 个下行端口
PCIe Bridge 0x060400 简单的 1:1 桥接,无端口扩展
Endpoint 0x030000 (VGA) / 0x010802 (NVMe) 终端设备:GPU、NVMe、网卡等

Switch 和 Bridge 的 class code 相同 (0x060400)—区别在于端口数量和 sysfs 子树结构。


2. sysfs 识别各层

2.1 识别 PCIe Domains (Root Complex)

每个 pci0000:XX 目录是一个独立的 PCIe domain,对应一个 Root Complex:

ls /sys/devices/ | grep pci

本环境输出(24 个 domain):

pci0000:00  pci0000:15  pci0000:26  ...  pci0000:7f  pci0000:80
pci0000:97  pci0000:a7  ...  pci0000:fe  pci0000:ff
# 各 domain 的设备数量
for d in /sys/devices/pci*; do
    count=$(ls "$d" 2>/dev/null | grep -c "^0000:")
    echo "$(basename $d): $count devices"
done

本环境(部分):

pci0000:00: 18 devices    ← 芯片组/VGA
pci0000:7f: 122 devices   ← Socket 0 高密度 I/O
pci0000:97: 5 devices     ← GPU 所在 domain
pci0000:ff: 122 devices   ← Socket 1 高密度 I/O

2.2 识别 Bridge vs Switch

Bridge 下游只有 1 个设备;Switch 有多个下游端口:

# 本环境:GPU 经单 Bridge 连接
ls /sys/devices/pci0000:97/0000:97:01.0/ | grep "^0000:"
# 0000:98:00.0           ← 仅 1 个下游设备 = Bridge,非 Switch

# Bridge class code
cat /sys/devices/pci0000:97/0000:97:01.0/class
# 0x060400               ← PCI-to-PCI bridge

如果有 Switch,会看到:

# 示例(非本环境):Switch 有多个下游端口
ls /sys/devices/pci0000:7f/0000:7f:00.0/ | grep "^0000:"
# 0000:80:00.0  0000:81:00.0  0000:82:00.0  ...  ← 多个下游设备

2.3 追踪设备完整路径

readlink -f /sys/bus/pci/devices/0000:98:00.0
# /sys/devices/pci0000:97/0000:97:01.0/0000:98:00.0
#                ↑RC      ↑Bridge       ↑GPU

解析:pci0000:97 (Root Complex) → 0000:97:01.0 (Bridge, Intel 0x352a) → 0000:98:00.0 (GPU)。


3. 本环境完整拓扑

Socket 0 (NUMA node 0)
├── pci0000:00  18 devices  (chipset, VGA, legacy)
├── pci0000:7e  37 devices  (I/O subsystem)
└── pci0000:7f  122 devices (高密度 I/O)

Socket 1 (NUMA node 1)
├── pci0000:97   5 devices  (GPU domain)
│     └── 97:01.0 [Bridge, Intel 0x352a]
│           └── 98:00.0 [RTX 5090, NVIDIA 0x2b85]
├── pci0000:d7          (NVMe domain: nvme0n1/1n1/2n1)
├── pci0000:fe  37 devices  (I/O subsystem)
└── pci0000:ff  122 devices (高密度 I/O)

关键观察:

  • GPU 独占一个 domain (pci0000:97),无其他高速设备共享 RC——这是最优拓扑
  • NVMe 分布在 domain d7(3 块 NVMe,nvme0-2n1,与 GPU 同在 Socket 1 / NUMA node 1)和 domain 7f/ff(高密度 I/O,各 122 devices)
  • GPU 与 3 块 NVMe 在同一个 Socket:GDS (GPU Direct Storage) 的 NVMe↔GPU 数据路径在本地 socket 内完成,无跨 UPI 开销,参见 GPU Direct Storage 基础。跨 socket 需经过 UPI(Ultra Path Interconnect,Intel 双路 CPU 之间的点对点互连总线,NUMA distance 21 vs 本地 10),会增加 ~2× 延迟

4. 识别 Root Port vs Switch Port

# Root Port 通常在 domain 根目录下 (BDF 的 device=00)
ls /sys/devices/pci0000:97/ | grep "0000:97:00"
# 0000:97:00.0  0000:97:00.1  0000:97:00.2  0000:97:00.4
# 这些是 Root Port (在 domain 的 bus 0 上)

# Bridge 在 Root Port 下游 (bus 01)
ls /sys/devices/pci0000:97/ | grep "0000:97:01"
# 0000:97:01.0  ← Bridge,连接在 bus 1 上

Root Port 的特征:BDF 中 bus = domain bus (通常是 0x97),device = 0x00。


5. 查看 Bridge 的上下游

# Bridge 的上游 (指向 Root Port)
# 通过 PCIe 拓扑推断:97:01.0 的上游是 97:00.x (某个 Root Port)

# Bridge 的下游设备
ls /sys/devices/pci0000:97/0000:97:01.0/ | grep "0000:"
# 0000:98:00.0  ← GPU

# 检查下游是否有更多 bridge (级联)
cat /sys/bus/pci/devices/0000:98:00.0/class
# 0x030000  ← VGA controller: 这是 Endpoint,不再级联

6. 总结

层级 本环境 如何识别
Root Complex 24 个 domain (pci0000:XX) /sys/devices/pci* 的数量
Root Port domain 内 BDF device=00 class = 0x060400 + bus=domain bus
PCIe Switch 不存在 下游有 ≥2 个 device 的 bridge
PCIe Bridge 97:01.0 (Intel 0x352a) class = 0x060400 + 下游仅 1 个 device
Endpoint 98:00.0 (RTX 5090) class 非 0x060400/0x060000

GPU 路径为最简拓扑:Root Complex → Bridge → GPU,无 Switch 引入额外延迟,无同级设备竞争带宽。


参考