图片无法显示,请右键点击新窗口打开图片

在传统服务器架构里,多台服务器可以通过网络交换机连接到整个机房,每个服务拥有自己的内存、CPU、存储和 GPU,服务器之间相互独立,服务器之间只有通过网络才能进行通信实现资源交换. 当需要为服务器扩容时,只能通过动态热插到指定服务器,新插入的内存仅仅作用于指定服务器. 在现代服务器集群里,资源池化的概念越来越重要,服务器可以弹性的从资源池里获得和释放所需的资源,也可实现资源的共享与独占.

图片无法显示,请右键点击新窗口打开图片

在资源池化的架构里,如上图内存资源实现了池化能力,服务器需要扩展内存时,可以弹性的从内存池中将内存绑定(Bind)到服务器即可使用,当服务器需要缩容内存时,则弹性的从服务器解绑(Unbind), 这样的架构既可以满足服务器对内存资源的需求,又可以根据业务场景弹性使用内存资源,最后可以充分利用内存池里面的资源.

图片无法显示,请右键点击新窗口打开图片

实现资源池化的方案很多,其中 CXL Pooling 模式也是资源池化的方案之一, Pooling 模式是一种资源管理机制,它允许多个主机或处理器访问并动态分配一组共享的硬件资源, CXL 的 Pooling 模式主要应用于内存、加速器和其他设备之间的共享资源使用场景. 在 Pooling 模式下,设备资源不是固定分配给单个主机,而是可以根据需求动态分配给多个主机,这种灵活性使得资源利用率最大化. CXL Pooling 模式可以根据资源类型和应用需求进行区分,常见的资源池化模式包括:

  • 内存池化(Memory Pooling): 在 CXL.mem 协议的支持下,内存设备可以被多个主机动态访问和分配, 每个主机可以从共享内存池中分配到一定的内存资源,并在完成任务后将内存释放回池中, 内存池化可以显著提高系统内存的利用率,并减少内存的浪费, 常见的是 CXL Type3 MLD/SLD 设备
  • 加速器池化(Accelerator Pooling): CXL.cache 和 CXL.mem 协议支持的加速器池化允许多个主机共享 GPU、FPGA 或其他加速器资源, 主机可以按需请求计算资源,并在任务完成后释放

图片无法显示,请右键点击新窗口打开图片

CXL 需要实现 Pooling 池化功能,那么硬件上必须包括: CXL SWITCH、CXL Type3 设备(SLD/MLD) 以及 Fabric Manager. 协议上必须支持 CXL2.0 及其以上, 每种硬件组件在 Pooling 模式下的作用如下:

  • CXL Switch/Fabric: CXL Switch 是 Pooling 模式的核心组件,负责在多个主机和设备之间路由请求,并协调资源的分配和访问, CXL 3.0 中的 Fabric 功能进一步扩展了资源池化的能力,允许支持更多设备、复杂的拓扑结构和更高效的资源调度.
  • Fabric Manager: Fabric Manager 管理资源池化的核心部分,负责协调资源池中设备的分配和释放, 它能够根据主机的工作负载需求,动态调整资源的分配,确保最优的性能和资源利用率
  • Type 3(SLD/MLD) 设备: CXL Type3 设备主要作为被动的内存拓展卡,由 Host 管理其内存的使用. SLD 由称为单逻辑设备,它可以将一个 Type3 设备虚拟成一个逻辑设备,而 MLD 则可以将一个 Type3 设备虚拟成多个逻辑设备, 主机统一时刻只能将一个端口连接到一个逻辑设备上.

通俗来讲,由于 MLD/SLD 设备同一时刻只能连接到一个主机 VH 的 vPPB 上,因此可以使用 Fabric Manager 动态或静态的将 SLD/MLD 设备绑定到指定主机端口,也可以从指定端口解绑,综合这些特性,CXL Pooling 可以为主机弹性提供独占的 CXL 设备. 从这些特性还可以看出 Pooling 提供的内存或者设备不具有并行共享的特性,而只能通过分时共享. CXL Pooling 模式的优点包括以下:

  • 高效资源利用: 通过动态分配资源,Pooling 模式避免了资源的长期闲置, 主机只在需要时请求资源,用完后将其释放回资源池,使得系统中的硬件资源能够服务更多的工作负载
  • 降低成本: 资源池化减少了为每个主机配置专用硬件资源的需求,从而降低了硬件成本和功耗. 多个主机可以共用一组设备,减少了购买和部署大量独立设备的必要性
  • 灵活性和可扩展性: Pooling 模式通过 CXL Fabric 提供了高度的灵活性和可扩展性. 系统可以根据工作负载需求增加更多的内存或加速器,而无需重新设计架构
  • 按需扩展: 随着主机数量和工作负载的增加,可以根据需要添加更多的资源到资源池中,轻松扩展系统的整体性能和能力
CXL Pooling Practice

图片无法显示,请右键点击新窗口打开图片

BiscuitOS 提供了 CXL Pooling 的实践环境,其 CXL 拓扑如上图, BiscuitOS 使用两个虚拟机作为两个服务器主机,并使用 QEMU 的 QMP 充当 Fabric Manager(FM). 在初始状态下,CXL Type3 物理设备作为 MLD 设备虚拟暴露出两个逻辑设备,两个逻辑设备并未绑定到任何主机的 VH 上. 在两个主机上电之后,FM 可以根据需求将 MLD 绑定到指定 VH 的 vPPB 上,也可以从指定 VH 的 vPPB 上进行解绑. 接下来在 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: x2 Host(VH) + MLD)  --->
  [*] Package  --->
      [*] HETEROGENEOUS MEMORY MANAGEMENT
          [*] CXL MLD: Multi Logical Device  --->

# 配置完毕保存,然后进行部署
make

# 切换到实践案例所在目录
cd output/linux-6.10-x86_64/package/BiscuitOS-CXL-MLD-default
# 准备依赖工具
make prepare
# 编译实践案例
make download
make build

图片无法显示,请右键点击新窗口打开图片

当第一个主机启动之后,使用 cxl 命令查看 CXL 拓扑结构,可以看到没有任何的 CXL Type3 设备被识别到,接着使用 lspci 命令查看 PCIe 总线,可以看到 CXL SWITCH(BDF 0E:00.0) 之下没有绑定任何 CXL Endpointer 设备. 接下来新启动一个终端来启动第二个主机,参考如下命令:

# 切换到 BiscuitOS 项目目录, 同理以 linux 6.10 X86 为例
cd BiscuitOS/output/linux-6.10-x86_64
# 直接启动第二个主机
./RunBiscuitOS-CXL.sh

图片无法显示,请右键点击新窗口打开图片

当第二个主机启动之后,使用 cxl 命令查看 CXL 拓扑结构,可以看到没有任何的 CXL Type3 设备被识别到,接着使用 lspci 命令查看 PCIe 总线,可以看到 CXL SWITCH(BDF 0E:00.0) 之下没有绑定任何 CXL Endpointer 设备. 此时两个主机已经环境已经部署完毕,两个主机 VH 的 vPPB 并没有绑定任何 MLD, 接下来使用 FM 进行 MLD 绑定. 首先选择第一个主机的终端,使用如下命令:

# 1. 按下快捷键进入 FM 模式: [Ctrl-A C]

# 2. 绑定 SLD
object_add memory-backend-file,id=CXL-MLD0,mem-path=/tmp/CXL-MLD0,share=on,size=256M,align=16M,offset=0
object_add memory-backend-file,id=CXL-MLD1,mem-path=/tmp/CXL-MLD0,share=on,size=256M,align=16M,offset=256M
device_add cxl-type3,bus=CXL-SWITCH0-DP0,volatile-memdev=CXL-MLD0,id=CXL-DDR0
device_add cxl-type3,bus=CXL-SWITCH0-DP1,volatile-memdev=CXL-MLD1,id=CXL-DDR1

# 3. 按下快捷键退出 FM 模式: [Ctrl-A C]

# 4. 重新遍历 PCIe 树
echo 1 > /sys/bus/pci/rescan

图片无法显示,请右键点击新窗口打开图片

执行完上面的命令之后,Fabric Manager 将第一台主机 VH 的 vPPB 绑定到了 MLD 设备上,此时可以看到主机识别两个 CXL Type3 设备,其由 DDR 构成且总容量为 512MiB, 接下来在第一台主机上访问该 CXL Type3 设备.

图片无法显示,请右键点击新窗口打开图片

  • cxl create-region -d decoder0.0 -m mem0 -s 512M -t ram -w 1 -g 4096 -u: 命令用于创建一个 CXL Region
  • cxl create-region -d decoder0.0 -m mem1 -s 512M -t ram -w 1 -g 4096 -u: 命令用于创建一个 CXL Region
  • cxl enable-region region0: 创建完毕之后使用该命令使能 CXL Region
  • cxl enable-region region1: 创建完毕之后使用该命令使能 CXL Region
  • daxctl reconfigure-device –mode=devdax dax0.0 –force: 将 CXL Type3 设备模式修改为 DEVDAX
  • daxctl reconfigure-device –mode=devdax dax1.0 –force: 将 CXL Type3 设备模式修改为 DEVDAX
  • BiscuitOS-CXL-SLD-default READ: 从 CXL Type3 设备上读取数据
  • BiscuitOS-CXL-SLD-default WRITE <MESSAGE>: 向 CXL Type3 设备写入数据

执行完这些命令之后,可以看到主机一可以正常访问 MLD 映射的 CXL Type3 设备,并向设备写入 “HELLO-BiscuitOS-HOSTA”, 那么接下来让 FM 动态解绑,并将 MLD 动态绑定到主机二 VH 的 vPPB 上, 参考如下命令:

# 0. 主机一按下快捷键进入 FM 模式: [Ctrl-A C]

# 1. FM 解绑 SLD
device_del CXL-DDR0
device_del CXL-DDR1
object_del CXL-SLD0
object_del CXL-SLD1

# 2. 主机二按下快捷键进入 FM 模式: [Ctrl-A C]

# 3. 绑定 SLD
object_add memory-backend-file,id=CXL-MLD0,mem-path=/tmp/CXL-MLD0,share=on,size=256M,align=16M,offset=0
object_add memory-backend-file,id=CXL-MLD1,mem-path=/tmp/CXL-MLD0,share=on,size=256M,align=16M,offset=256M
device_add cxl-type3,bus=CXL-SWITCH0-DP0,volatile-memdev=CXL-MLD0,id=CXL-DDR0
device_add cxl-type3,bus=CXL-SWITCH0-DP1,volatile-memdev=CXL-MLD1,id=CXL-DDR1

# 4. 按下快捷键退出 FM 模式: [Ctrl-A C]

# 5. 重新在第二主机上遍历 PCIe 树
echo 1 > /sys/bus/pci/rescan

图片无法显示,请右键点击新窗口打开图片

执行完上面的命令之后,Fabric Manager 将第二台主机 VH 的 vPPB 绑定到了 MLD 设备上,此时可以看到主机识别两个 CXL Type3 设备,其由 DDR 构成且总容量为 512MiB, 而主机一已经看不到 CXL MLD 设备了. 接下来在第二台主机上访问该 CXL Type3 设备.

图片无法显示,请右键点击新窗口打开图片

  • cxl create-region -d decoder0.0 -m mem0 -s 512M -t ram -w 1 -g 4096 -u: 命令用于创建一个 CXL Region
  • cxl create-region -d decoder0.0 -m mem1 -s 512M -t ram -w 1 -g 4096 -u: 命令用于创建一个 CXL Region
  • cxl enable-region region0: 创建完毕之后使用该命令使能 CXL Region
  • cxl enable-region region1: 创建完毕之后使用该命令使能 CXL Region
  • daxctl reconfigure-device –mode=devdax dax0.0 –force: 将 CXL Type3 设备模式修改为 DEVDAX
  • daxctl reconfigure-device –mode=devdax dax1.0 –force: 将 CXL Type3 设备模式修改为 DEVDAX
  • BiscuitOS-CXL-SLD-default READ: 从 CXL Type3 设备上读取数据

执行完这些命令之后,可以看到主机二可以正常访问 MLD 映射的 CXL Type3 设备,并直接从 CXL Type3 设备上读到了主机一写入的字符串 “HELLO-BiscuitOS-HOSTA”, 此时可以验证 FM 已经将同一个 MLD 动态绑定到新主机 VH 的 vPPB 上,形成第二个主机的 CXL Type3 设备. 至此实践完毕.

图片无法显示,请右键点击新窗口打开图片