在 CXL1.0/1.1 架构里,CXL 设备通过 CXL RootPort 直接连接到单主机上,单主机通过单一的接口就可以访问 type1、type2 和 type3 设备, 此时 CXL 设备并不能被多台主机进行共享,其能被同一台主机的多个处理器进行共享访问.
CXL2.0 引入了许多新的特性,其中 CXL Switch 是一个关键功能,旨在提高 CXL 设备之间的互联性和可扩展性. CXL Switch 允许多个 CXL 设备通过单一连接与主机 CPU 进行通信,从而支持更复杂的架构和更高的带宽. CXL Switch 可以连接多个 CXL 设备,包括 Type1、Type2 和 Type3 设备, 另外多个主机可以同时连接到同一个 CXL SWITCH 上,这种多连接能力使得在数据中心多台主机可以通过单一的端口连接多个加速器和内存扩展设备,从而提高了系统的灵活性和可扩展性.
在 CXL2.0 SWITCH 架构里,CXL SWITCH 位于一台独立的服务器(该主机用于管理 CXL),并通过 Fabric Manager 为其他主机提供统一的接口服务,协助管理 CXL SWITCH. CXL SWITCH 服务器提供 CDFP Connecter, 其他主机则通过 CDFP Cable 连接到 CXL SWITCH 服务器上.
CDFP Cable(Cumulative Data Flow Protocol Cable) 是一种用于高带宽、低延迟数据传输的电缆,主要用于连接数据中心中的高速接口,特别是在使用 CDFP 接口的设备之间, 这种电缆通常用于数据中心交换机、服务器和存储设备的互联. CDFP Cable 支持高达 400 Gbps 或更高的带宽,适合需要大数据吞吐量的应用, 另外设计上旨在提供低延迟传输,适合对延迟敏感的应用场景.
Host 需要一个 CDFP 转接模块,该模块通常会包含一个 CDFP 接口和一个 PCIe 接口,该模块可以将 Host 的 PCIe 输出转换为 CDFP 信号,以便与 CXL Switch 连接. CXL Switch 本身需要配备多个 CDFP 端口,以支持连接多个 Host, 这些端口使得 Switch 可以与多台设备进行高带宽连接.
在传统的数据中心,服务器机箱是堆叠机柜里,每个服务器包含 CPU、内存、加速器、网络设备和存储,服务器通过以太网以及机架顶端交换机互相通信. 但随着 CXL 在数据中心的应用,服务器架构将发生变化, 首次看到内存分解,可以在服务器之间动态分配内存资源,在未来一段实践,服务器将拥有专用内存. 然而,最终架构将变成计算、内存和 I/O 独立机架,此外机箱之间通过 CXL 互联, 并且一些曾用于传输高速以太网的技术也将用于 CXL.
CXL SWITCH TOPOLOGY
CXL2.0 引入 CXL SWITCH 之后,多个主机可以通过 CXL SWITCH 服务器共享 CXL 设备,同时,同一台主机也可以连接多台 CXL SWITCH 服务器,以此访问散落在 CXL SWITCH 服务器上的 CXL 设备, 这样的拓扑可以带来以下几点好处:
- 更高的带宽: 通过连接多个 CXL SWITCH,可以显著增加可用的总带宽,使主机能够处理更多数据流和更高的工作负载
- 分散数据流: 多个 CXL SWITCH 可以分散来自主机的请求,降低单个 CXL SWITCH 的负载,提高整体性能和响应速度
- 增加可靠性: 如果一台 CXL SWITCH 出现故障,主机仍然可以通过其他 CXL SWITCH 进行数据传输,提高系统的可靠性和可用性
- 异构计算支持: 主机可以连接不同类型的加速器或存储设备,通过多个 CXL SWITCH 实现更灵活的资源管理,适应不同的应用需求
- 增强资源利用: 多个 CXL SWITCH 允许主机在不同的设备之间进行内存共享,从而提高内存的利用率,减少内存瓶颈
- 优化网络拓扑: 这种配置可以简化数据中心的网络架构,使其更容易管理和扩展
CXL3.0 允许多个 CXL Switch 级联连接,形成多级拓扑, 这种结构可以在大规模系统中提供更高的带宽和更好的资源管理. CXL3.0 SWITCH 可以支持中心化的网络架构(如一个核心 SWITCH 连接所有设备)以及去中心化的架构(每个设备可以直接连接到多个 SWITCH),增强了网络灵活性. CXL3.0 SWITCH 可以形成树形拓扑,其中主 SWITCH 作为根节点,多个下级 SWITCH 作为子节点,适用于大规模数据中心,方便管理和扩展. 另外 CXL3.0 的拓扑结构可以连接多种类型的设备(如 CPU、GPU、FPGA 等),实现异构计算资源的共享,提升计算能力.
CXL VCS
由于 CXL 基于 PCIe 构建,那么先了解 PCIe SWITCH. 在 PCIe SWITCH 内部,存在上游端口(Upstream Port)和下游端口(Downstream Port), 上游端口是连接到主机(通常是 CPU 或主板)的一侧端口, 它负责接收来自主机的 PCIe 请求,并将这些请求转发到下游端口或其他设备. 下游端口是连接到其他设备(如 GPU、存储设备、网络接口等)的端口, 它负责将数据和命令从上游端口转发到下游设备. 在 PCIe SWITCH 内部存在一条 PCIe 总线,其总线号在深度优先算法上紧接着上游端口所有的 PCIe 总线, 其内部的所有下游端口都位于内部 PCIe 总线上, 因此根据深度优先算法,假设这些下游端口直接连接 EP,那么每个下游端口的下游 PCIe 总线号相邻.
CXL SWITCH 支持 VCS(Virtual CXL SWITCH) 功能,VCS 是一种逻辑功能,允许多个主机和设备在 CXL 网络中共享和管理资源,VCS 通过提供 VH 抽象,将 CXL SWITCH 虚拟化成多个 CXL SWITCH,其由 vPPB 组成,vPPB(虚拟 PCI-to-PCI 桥接器),位于 VCS 内部,由主机拥有,可以绑定到一个端口,该端口可以是未连接的、连接到 PCIe 组件的或连接到 CXL 组件. 每个 VCS 之间实现资源隔离, 例如上图是一个单 VCS 的架构,其具有如下特点:
- 必须有一个单一的上游端口(USP)
- 必须有一个或多个下游端口(DSP)
- DSP 必须支持在 CXL 模式或 PCIe 模式下操作
- 所有非 MLD(包括 PCIe 和 SLD)端口支持在虚拟 PPB(vPPB)下的单一虚拟层次结构
- 下游交换端口必须能够支持 RCD 模式(CXL1.x)
- 单个 VCS 交换机的 Fabric Manager(FM)是可选的
- 必须支持端口的 CXL 扩展 DVSEC, DVSEC 定义了支持 CXL.io 解码以支持交换机下的 RCD 的寄存器,以及用于 CXL 内存解码的寄存器. CXL.io 的地址解码是对 vPPB 支持的地址解码机制的补充
CXL SWITCH 支持 Multiple VCS 功能,其在一个 CXL SWITCH 中存在多个 VCS 实例,每个 VCS SWITCH 可以管理不同的 VH,也就是每个 VCS 之间相互独立,实现对资源的独立控制和管理,这种结果运行不同的主机和设备在同一个物理交换机上共享资源,同时维持隔离和性能的优化. 如上图,每个主机通过 CXL RootPort 连接到 CXL SWITCH 的一个上游 vPPB(USP), 其 VCS 里包含多个下游 vPPB(DSP), VCS0、VCS1 和 VCS2 之间相互隔离. Multiple VCS 需要具备以下条件:
- 必须有多个上游端口(USP/US vPPB)
- 每个 VCS 必须有一个或多个下游虚拟 PPB(DS vPPB)
- 上游虚拟 PPB(US vPPB)与物理端口的初始绑定,以及 VCS 的结构(包括虚拟 PPB 的数量、默认的虚拟 PPB 能力结构和任何下游虚拟 PPB 的初始绑定)通过交换机厂商特定的方法定义
- 每个下游端口(DSP)必须绑定到一个 PPB 或虚拟 PPB(vPPB)
- 对于多个 VCS 交换机,Fabric Manager(FM) 是可选的, 对于需要绑定/解绑或支持 MLD 端口的多个 VCS 交换机,则需要 FM. 每个 DSP 可以通过 FM 协调的管理热插拔流程重新分配到不同的 VCS 配置后,每个 USP 及其相关的下游虚拟 PPB 形成一个单一的 VCS 交换机,并按单一 VCS 交换机规则运行
- DSP 必须支持在 CXL 模式或 PCIe 模式下操作, 所有非 MLD 端口支持在下游交换端口下的单一虚拟层次结构, DSP 必须能够支持 RCD 模式
CXL SWITCH Practice
BiscuitOS 目前支持 CXL2.0 SWITCH 的实践,本节用于介绍如何在 BiscuitOS 上实践上图所示的 CXL 拓扑, 项目包含了一台主机,CPU 通过南桥转 CXL Host Bridge,其引入 PCI:0C 总线,直接连接到 CXL Root Complex,CXL RC 里仅包含一个 CXL RootPort,此时 CXL RootPort 的 BDF 为 “0C:00.0”. RP 通过 “BUS-D” 总线连接到 CXL SWITCH 上,SWITCH 只虚拟了一个 VCS,那么 Upstream Port(UP vPPB) 的 BDF 为 “0D:00.0”, VCS 通过 “BUS-E” 总线连接 4 个 Downstream Port(DP vPPB), 每个 DP 都连接到一个 PCIe 插槽上. 实践案例里只有 “BUS-F” 连接的 PCIe 插槽上插入一个 “CXL Type3” 设备,该设备的 BDF 为 “0F:00.0”. 接下来在 BiscuitOS 实践该场景, 参考如下命令:
# 切换到 BiscuitOS 项目目录
cd BiscuitOS
# 选择开发环境,如果已经选择过可以跳过,这里与 linux 6.10 X86 为例
make linux-6.10-x86_64_defconfig
# 通过 Kbuild 选择需要部署的应用程序
make menuconfig
[*] DIY BiscuitOS/Broiler Hardware --->
[*] CXL: Compute Express Link
CXL Hardware Topology (CXL2.0: x1 VCS + x1 Type DDR) --->
[*] Package --->
[*] HETEROGENEOUS MEMORY MANAGEMENT
[*] CXL: CXL.mem AS SYSTEM RAM --->
# 配置完毕保存,然后进行部署
make
# 切换到实践案例所在目录
cd output/linux-6.10-x86_64/package/BiscuitOS-CXL-MEMORY-default
# 准备依赖工具
make prepare
# 编译实践案例
make download
make build
BiscuitOS 启动之后,可以使用 CXL 工具查看 CXL 的拓扑结构,拓扑与 CXL 硬件对应关系是: “root0” 对应 “CXL Root Complex”, “port1” 对应 “CXL RootPort”, “port2” 对应 CXL SWITCH,其 dport 对应 CXL SWITCH 的Downstream Port, 最后 “endpoint3” 对应 “CXL Type3” 设备. 接着使用 lspci 工具查看 PCIe 的拓扑信息,可以看到 CXL 使用了 “PCI-0C”,并且 BDF 可以和之前介绍的对应上,其中 “CXL Type3” 设备的 BDF 为 “0F:00.0”.
硬件拓扑分析完毕之后,将插入到 CXL SWITCH 下游端口的 CXL Type3 设备,作为 DDR 内存插入到系统里,通过一系列的 cxl 命令,系统新增了一个 NODE NODE,该 NODE 存在 ZONE_MOVABLE, 并且系统物理内存增加了差不多 500MiB.