当将 CXL Type3 设备内部存储空间 DPA,并映射到系统物理地址空间形成 HPA 区域,CXL 使用 CXL REGION 为系统屏蔽了 HPA 到 DPA 映射的细节,操作系统可以将 HPA 当做正常的物理区域使用. 为了方便操作系统对 HPA 的使用,操作系统可以将 CXL REGION 切换成不同的模式,以此以不同的形态展现在系统硬件层面,主要包括三种模式: SYSTEM-RAM、DEVDAX 和 FSDAX.

SYSTEM-RAM 模式 是 CXL REGION 的一种常见的配置模式,通过将 CXL Type3 设备的内存资源无缝集成到操作系统的主内存(DRAM)中,实现对物理内存容量的透明扩展. 在此模式下,CXL 内存被视为系统的 NUMA(Non-Uniform Memory Access)节点的一部分,由操作系统统一管理,应用程序无需修改即可直接使用. CXL Type3 设备可以是 PMEM,也可以是 SRAM, 当 CXL Type3 设备的 CXL REGION 创建完毕之后,可以借助 cxl-ctrl、ndctl 和 daxctl 工具设置 CXL REGION 的模式, 接下来边实践边进行讲解, 实践案例在 BiscuitOS 上的部署逻辑如下:

# 切换到 BiscuitOS 项目目录
cd BiscuitOS
# 通过 Kbuild 选择需要部署的应用程序
make menuconfig

  [*] DIY BiscuitOS/Broiler Hardware  --->
      <*> Intel Q35
      [*] CXL: Compute Express Link
            CXL Hardware Topology (CXL2.0: x1 VCS + x1 Type DDR)  --->
  [*] package --->
      [*] HETEROGENEOUS MEMORY MANAGEMENT  --->
          [*] CXL REGION: SYSTEM-RAM MODE  --->


# 配置完毕保存,然后进行部署
make
# 安装必备工具
cd BiscuitOS/output/linux-6.10-x86_64/package/BiscuitOS-CXL-REGION-SYSRAM-default
# 第一次执行如下命令
make prepare
make download
make tar
make configure
# 运行 BiscuitOS
make build

当 BiscuitOS 运行之后,直接运行 RunBiscuitOS.sh, 该脚本包含了实践所需的全部命令, 在运行实践案例之前,使用 free 和 numactl 命令查看当前内存信息,接着运行脚本,可以看到脚本创建了一个 CXL REGION,并将 CXL REGION 的模式设置为 SYSTEM-RAM 模式,接着可以看到实践案例从 CXL REGION 的内存里读到数据,最后通过 free 和 numactl 命令可以看到系统物理内存数量增加,并且新增加了一个 NUMA NODE. 接下来查看一下实践案例源码:

实践案例由一个应用程序构成,其在 21 行调用 mmap 函数分配一段匿名内存,然后在 32 行对匿名内存进行写操作,并紧接着从该内存读出刚写入的数据,最后在 36 行调用 munmap 释放内存. 实践案例并未看出为了适配 CXL REGION SYSTEM-RAM 模式做的修改,因此应验了之前分析的,SYSTEM-RAM 可以提供透明扩展能力. 接下来看一下 CXL REGION SYSTEM-RAM 创建过程:

# 清空所有的 CXL REGION
cxl destroy-region -f all
# 创建一个新的 CXL REGION
#   大小为 512M, 交织粒度为 4096, 来自一个 CXL Type3 设备 mem0
cxl create-region -d decoder0.0 -m mem0 -s 512M -t ram -w 1 -g 4096 -u
# 使能 CXL REGION
cxl enable-region region0

# 将 CXL REGION 设置为 SYSTEM-RAM 模式
daxctl reconfigure-device  -N --mode=system-ram dax0.0 --force

当 CXL REGION 的模式设置为 SYSTEM-RAM 之后,系统会通过热插(HotPlug) 的方式向系统新插入一个 NUMA NODE, 该 NUMA NODE 上不绑定任何 CPU,因此称为 CPULESS, 即所有的 CPU 访问该 NUMA NODE 上的内存都是远端内存(REMOTE MEMORY). CXL Type3 设备的内存就映射到该 NUMA NODE 上. 另外内核会为该 NUMA NODE 创建一个 MOVABLE 的 ZONE,并为这个 ZONE 创建一个独立的 BUDDY 分配器. 要从 CXL MEMORY 上分配内存,对于应用程序需要将应用程序绑定到该 NUMA NODE,而对于内核线程则需要将 page 的 NUMA-ID 设置为该 NUMA NODE. 那么接下来实践案例介绍内核线程如何使用 SYSTEM-RAM 模式下的 CXL REGION, 实践案例在 BiscuitOS 上的部署逻辑如下:

# 切换到 BiscuitOS 项目目录
cd BiscuitOS
# 通过 Kbuild 选择需要部署的应用程序
make menuconfig

  [*] DIY BiscuitOS/Broiler Hardware  --->
      <*> Intel Q35
      [*] CXL: Compute Express Link
            CXL Hardware Topology (CXL2.0: x1 VCS + x1 Type DDR)  --->
  [*] package --->
      [*] HETEROGENEOUS MEMORY MANAGEMENT  --->
          [*] CXL SYSTEM-RAM MODE ON KERNEL  --->


# 配置完毕保存,然后进行部署
make
# 安装必备工具
cd BiscuitOS/output/linux-6.10-x86_64/package/BiscuitOS-CXL-SYSRAM-KERNEL-default
# 第一次执行如下命令
make prepare
make download
make tar
make configure
# 运行 BiscuitOS
make build

当 BiscuitOS 运行之后,直接运行 RunBiscuitOS.sh, 该脚本包含了实践所需的全部命令, 在运行实践案例之前,使用 free 和 numactl 命令查看当前内存信息,接着运行脚本,可以看到脚本创建了一个 CXL REGION,并将 CXL REGION 的模式设置为 SYSTEM-RAM 模式,接着可以看到实践案例从 CXL REGION 的内存里读到数据,并打印了物理页所在的 ZONE 信息. 最后通过 free 和 numactl 命令可以看到系统物理内存数量增加,并且新增加了一个 NUMA NODE. 接下来查看一下实践案例源码:

实践案例由一个内核模块构成,其在 21 行调用 alloc_pages_node 函数从 CXL_NODE 里分配一个物理页,然后在 28 行获得物理页对应的线性映射区虚拟地址,并对虚拟内存进行读写操作. 最后在 35 行调用 __free_page 函数是否分配的内存. 以上便是内核线程或者内核态使用 CXL 内存的案例. 接下来分析用户进程如何使用 CXL 内存,实践案例在 BiscuitOS 上的部署逻辑如下:

# 切换到 BiscuitOS 项目目录
cd BiscuitOS
# 通过 Kbuild 选择需要部署的应用程序
make menuconfig

  [*] DIY BiscuitOS/Broiler Hardware  --->
      <*> Intel Q35
      [*] CXL: Compute Express Link
            CXL Hardware Topology (CXL2.0: x1 VCS + x1 Type DDR)  --->
  [*] package --->
      [*] HETEROGENEOUS MEMORY MANAGEMENT  --->
          [*] CXL SYSTEM-RAM MODE ON USERSPACE  --->


# 配置完毕保存,然后进行部署
make
# 安装必备工具
cd BiscuitOS/output/linux-6.10-x86_64/package/BiscuitOS-CXL-SYSRAM-USERSPACE-default
# 第一次执行如下命令
make prepare
make download
make tar
make configure
# 运行 BiscuitOS
make build

当 BiscuitOS 运行之后,直接运行 RunBiscuitOS.sh, 该脚本包含了实践所需的全部命令, 在运行实践案例之前,使用 free 和 numactl 命令查看 当前内存信息,接着运行脚本,可以看到脚本创建了一个 CXL REGION,并将 CXL REGION 的模式设置为 SYSTEM-RAM 模式,接着可以看到实践案例>从 CXL REGION 的内存里读到数据,最后通过 free 和 numactl 命令可以看到系统物理内存数量增加,并且新增加了一个 NUMA NODE. 接下来查看>一下实践案例源码:

实践案例由一个应用程序构成,其在 21 行调用 mmap 函数分配一段匿名内存,然后在 32 行对匿名内存进行写操作,并紧接着从该内存读出刚写入的数据,最后在 36 行调用 munmap 释放内存. 应用程序启动时,需要使用 “numactl –membind=1” 将其绑定到 CXL NUMA NODE 上. 实践案例并未看出为了适配 CXL REGION SYSTEM-RAM 模式做的修改,因此应验了之前分析的,SYSTEM-RAM 可以提供透明扩展能力, 以上便是用户进程在 CXL SYSRAM 模式下使用 CXL 内存的方法.

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