cxl 工具为 CXL 平台提供枚举和配置命令,其包含 zero-labels、read-labels、write-labels、disable-memdev、enable-memdev、reserve-dpa、free-dpa、disable-port、enable-port、set-partition、disable-bus、create-region、enable-region、disable-region、destroy-region、monitor 等子命令,本文用于详细介绍各子命令的使用方法. 开发者可以结合 BiscuitOS 边实践边学习,其在 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 Type3 PMEM)  --->
  [*] Package  --->
      [*] CXL Tools: cxl/ndctl/daxctl

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

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

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

当 BiscuitOS 启动之后,可以直接使用 “lspci-common -vt” 先查看 CXL 总线拓扑结构,然后直接使用 cxl 命令进行操作. 接下对 cxl 命令进行详细介绍:

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


create-region
cxl create-region [<options>]

create-region 子命令用于设置组成 CXL REGION 的 CXL MEMDEV 属性,以此创建一个新的 CXL REGION. 在 CXL 架构里,CXL REGION 为操作系统屏蔽 CXL DPA 之间错综复杂的映射关系,提供统一管理的 HPA 地址映射,因此 CXL REGION 可能由一个或者多个 CXL MEMDEV 构成,该子命令用于设置这些 CXL MEMDEV 属性,让其提供统一的 HPA 区域. options 支持以下参数:

  • -b/–bus=: 限制操作在指定总线上进行, 在有的平台上支持多条 CXL BUS, 因此需要使用该命令指定所使用的 CXL BUS 信息.
  • -m/–memdevs <MEMDEV …>: 指定目标的非选项参数是指 memdev 设备名称. 如果未指定此选项并且没有指定目标,create-region 将在内部使用等效的 cxl list -M -d $decoder 作为目标列表. 请注意,根据拓扑结构,例如使用交换机,自动目标列表的顺序可能无效,需要手动指定目标列表. MEMDEV 用于指定构成 CXL REGION 的 CXL MEMDEV 信息,可以是一个 CXL MEMDEV,也可以是多个 CXL MEMDEV,此时将多个 CXL MEMDEV 并排中间空格列出即可.
  • -s/–size=: 指定新 CXL REGION 的总大小, 这是可选的,默认情况下会使用可能的最大大小. 最大可能大小受到根解码器中剩余的连续空闲 HPA 空间和组件 memdevs 中可用 DPA 空间的限制. 大小需要按 256MiB 大小对齐.
  • -t/–type=: 指定 CXL REGION 类型 pmem 或 ram. 默认为根解码器能力,如果不明确,则默认为 pmem.
  • -U/–uuid=: 为新区域指定一个 UUID. 通常不需要指定,因为默认会生成一个, 仅适用于 pmem 区域
  • -w/–ways=: 新 CXL REGION 的交错路径数量,也就是 CXL REGION 由几个 CXL MEMDEV 组成. 如果提供了 “–memdevs”,则此应该等于指定的 memdevs 数量. 如果未指定 –ways,将根据提供的 memdev 目标数量进行确定
  • -g/–granularity=: 新 CXL REGION 的交错粒度, 必须匹配所选根解码器(如果提供)的粒度, 该信息来自 CFMWS. 如果根解码器在多个主桥上交错,则此值必须匹配该粒度. 否则对于非交错解码窗口,可以指定任何粒度,只要所有设备支持该设置即可
  • -d/–decoder=: 新 CXL REGION 应创建在其下的根解码器, 如果未提供,将选择支持最大交错的第一跨主桥(如果可用)解码器
  • -u/–human: 默认情况下,命令将输出机器易读的原始整数数据, 使用此标志时,表示存储大小的数字将格式化为带单位的人类易读字符串,其他字段将转换为十六进制字符串
  • –debug: 打开额外的调试信息,包括库调试信息
# 移除所有的 CXL REGION
cxl destroy-region -f all
# 基于 CXL MEMDEV mem0 创建一个长度为 512M CXL REGION,其内存颗粒是 PMEM,由一个 CXL MEMDEV 设备构成,其交织粒度为 4096 字节
cxl create-region -d decoder0.0 -m mem0 -s 512M -t pmem -w 1 -g 4096 -u
# 使能 CXL REGION (region0 为新建的 CXL REGION)
cxl enable-region region0
# 查看新创建 CXL REGION 信息
cxl list -R

如果区域创建操作成功,将在标准输出(stdout)中以 JSON 格式生成一个区域对象. 如果指定的参数无法满足合法配置,则将在标准错误输出(stderr)中返回相应的错误信息.

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

enable-region
cxl enable-region <region> [<options>]

enable-region 命令用于启用 CXL REGION,启用成功之后可以将 CXL REGION 配置成不同的模式,以便操作系统使用. “region” 参数指定要启用的 CXL REGION,其也可以是 all, 用于启用所有的 CXL REGION, 对于 “options” 命令,其支持以下参数:

  • -b/–bus=: 限制操作仅作用于指定的总线
  • -d/–decoder=: 限制操作仅作用于指定的根解码器。只有作为指定解码器子项的区域会被操作
  • –debug: 启用额外的调试信息,包括库调试信息
# 移除所有的 CXL REGION
cxl destroy-region -f all
# 基于 CXL MEMDEV mem0 创建一个长度为 512M CXL REGION,其内存颗粒是 PMEM,由一个 CXL MEMDEV 设备构成,其交织粒度为 4096 字节
cxl create-region -d decoder0.0 -m mem0 -s 512M -t pmem -w 1 -g 4096 -u
# 使能 CXL REGION (region0 为新建的 CXL REGION)
cxl enable-region region0
# 查看新创建 CXL REGION 信息
cxl list -R

如果区域创建操作成功,将输出使能 CXL REGION 的数量. 使能失败则输出使能 CXL REGION 数量为 0.

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

disable-region
cxl disable-region <region> [<options>]

disable-region 命令用于禁止 CXL REGION,禁止成功之后,系统不能在使用在使用该 CXL REGION,换句话说,当前 CXL REGION 被配置成不同模式的内容将被禁止,cxl list 也无法查看该 CXL REGION. “region” 参数指定要禁止的 CXL REGION,其也可以是 all, 用于禁止所有的 CXL REGION, 对于 “options” 命令,其支持以下参数:

  • -b/–bus=: 限制操作仅作用于指定的总线
  • -d/–decoder=: 限制操作仅作用于指定的根解码器。只有作为指定解码器子项的区域会被操作
  • –debug: 启用额外的调试信息,包括库调试信息
# 移除所有的 CXL REGION
cxl destroy-region -f all
# 基于 CXL MEMDEV mem0 创建一个长度为 512M CXL REGION,其内存颗粒是 PMEM,由一个 CXL MEMDEV 设备构成,其交织粒度为 4096 字节
cxl create-region -d decoder0.0 -m mem0 -s 512M -t pmem -w 1 -g 4096 -u
# 使能 CXL REGION (region0 为新建的 CXL REGION)
cxl enable-region region0
# 查看新创建 CXL REGION 信息
cxl list -R
# 禁止 CXL REGION
cxl disable-region region0
# 查看所有 CXL REGION 信息
cxl list -R

如果区域禁止操作成功,将输出禁止 CXL REGION 的数量. 禁止失败则输出禁止 CXL REGION 数量为 0. 一个 CXL REGION 被禁止之后,可以使用 “cxl enable-region” 命令再次使能该 CXL REGION.

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

destroy-region
cxl destroy-region <region> [<options>]

destroy-region 命令用于摧毁 CXL REGION,摧毁成功之后,CXL 子系统不在存在该 CXL REGION,换句话说,”/sys/bus/cxl/devices” 目录下将看不到该 CXL REGION. “region” 参数指定要摧毁的 CXL REGION,其也可以是 all, 用于摧毁所有的 CXL REGION, 对于 “options” 命令,其支持以下参数:

  • -b/–bus=: 限制操作仅作用于指定的总线
  • -f/–force: 即使 CXL REGION 处于激活状态,也可以强制摧毁该 CXL REGION
  • -d/–decoder=: 限制操作仅作用于指定的根解码器。只有作为指定解码器子项的区域会被操作
  • –debug: 启用额外的调试信息,包括库调试信息
# 移除所有的 CXL REGION
cxl destroy-region -f all
# 基于 CXL MEMDEV mem0 创建一个长度为 512M CXL REGION,其内存颗粒是 PMEM,由一个 CXL MEMDEV 设备构成,其交织粒度为 4096 字节
cxl create-region -d decoder0.0 -m mem0 -s 512M -t pmem -w 1 -g 4096 -u
# 使能 CXL REGION (region0 为新建的 CXL REGION)
cxl enable-region region0
# 查看新创建 CXL REGION 信息
cxl list -R
# 摧毁 CXL REGION
cxl destroy-region region0
# 查看所有 CXL REGION 信息
cxl list -R

如果 CXL REGION 摧毁操作成功,将输出摧毁 CXL REGION 的数量. 摧毁失败则输出摧毁 CXL REGION 数量为 0.

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

monitor
cxl monitor [<options>]

monitor 命令用于监控内核发出的 CXL 追踪事件,将其转换为 JSON 对象,并将 JSON 格式的通知输出到标准输出或日志文件. 对于 “options” 命令,其支持以下参数:

  • -l/–log=: 将日志消息发送到指定目标
    • ": 将日志消息发送到指定的 , 如果 fopen() 无法打开 ,日志消息将转发到 syslog
    • “standard”: 将消息发送到标准输出. 如果指定了”–daemon”,默认日志目标为 /var/log/cxl-monitor.log,否则为标准输出. 注意如果指定了 “–daemon”,标准输出和 的相对路径将不起作用
  • –daemon: 以守护程序的方式运行监视器
  • -v/–verbose: 输出更多调试消息
  • -u/–human: 默认情况下,命令输出机器友好的原始整数数据, 使用此标志后,表示存储大小的数字将格式化为具有单位的人类可读字符串,其他字段将转换为十六进制字符串
# 记录 CXL 事件信息
cxl monitor --daemon --log=/var/log/cxl-monitor.log
# 实时查看日志
tail -f /var/log/cxl-monitor.log
# 浏览日志
less /var/log/cxl-monitor.log

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

disable-bus
cxl disable-bus <root0> [<root1>..<rootN>] [<options>]

disable-bus 命令用于关闭整条 CXL BUS, 需要指定需要关闭 CXL BUS 的 rootX 信息,一旦关闭之后, “/sys/bus/cxl” 目录下关于该 CXL BUS 所有信息将被移除, 也就是 CXL 子系统里将不再包含该 CXL BUS 的内容. 对于 “options” 命令,其支持以下参数:

  • -f/–force: 危险操作! 当工具判断某个子 memdev 正在被使用时,此选项会覆盖安全措施,允许禁用总线, 请注意,CXL 内存范围可能已由平台固件建立,禁用活动设备类似于从运行系统中强行移除内存
  • –debug: 如果 cxl 工具是在禁用调试的情况下构建的,此选项将开启调试信息
# 关闭指定 CXL BUS
cxl disable-bus root0
# 处于安全保护想,需要手动禁止指定的 CXL MEMDEV
cxl disable-memdev mem0
# 重试关闭 CXL BUS,或者强制关闭 CXL BUS
cxl disable-bus root0 -f

如果没有使用 “-f” 选项,那么系统会处于安全考虑,在 CXL BUS 下有激活态的 CXL MEMDEV,则不允许关闭 CXL BUS,除非将 CXL MEMDEV 关闭之后才能关闭 CXL BUS. 另外可以直接使用 “-f” 强制关闭 CXL BUS.

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

enable-memdev
cxl enable-memdev <mem0> [<mem1>..<memN>] [<options>]

enable-memdev 命令用于使能或热插一个 CXL MEMDEV. CXL MEMDEV 通常在初次设备发现时自动启用, 如果它被手动禁用了,此命令可以触发内核重新激活它. 这涉及检测 HDM 解码器的状态,并验证设备层级中的每个端口是否启用了 CXL.mem. 对于 “options” 命令,其支持以下参数:

  • -S/–serial: 将 参数解释为一系列序列号,而不是内存设备的 ID 号
  • -v: 启用库中的详细调试信息
# 使能/热插 CXL MEMDEV
cxl enable-memdev mem0
# 使能/热插所有的 CXL MEMDEV
cxl enable-memdev all
# 查看所有使能的 CXL MEMDEV
cxl list -M

如果成功使能 CXL MEMDEV, 则输出成功使能的数量, 如果失败则输出使能成功的数量为 0.

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

disable-memdev
cxl disable-memdev <mem0> [<mem1>..<memN>] [<options>]

disable-memdev 命令用于禁止或热拔一个或多个 CXL MEMDEV. 对于 “options” 命令,其支持以下参数:

  • -S/–serial: 不是将 参数解释为 memdev ID 号,而是解释为一个序列号列表
  • -f/–force: 危险! 覆盖安全措施,即使工具判断 memdev 正在被使用中也尝试禁用设备. 请注意,CXL 内存范围可能已由平台固件建立,禁用一个活动设备相当于从运行的系统中强制移除内存
  • -v: 在库中打开详细的调试消息
# 禁止/热拔 CXL MEMDEV
cxl disable-memdev mem0
# 禁止/热拔所有的 CXL MEMDEV
cxl disable-memdev all
# 强制禁止/热拔 CXL MEMDEV
cxl disable-memdev mem0 -f
# 查看所有使能的 CXL MEMDEV
cxl list -M

如果成功禁止 CXL MEMDEV, 则输出成功禁止的数量, 如果失败则输出错误信息.

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

enable-port
cxl enable-port <port0> [<port1>..<portN>] [<options>]

enable-port 命令用于激活或热插一个或多个 CXL PORT, 通常情况下,端口会在设备初始发现时自动启用. 然而如果它被手动禁用,此命令可以触发内核重新激活. 这个过程涉及检测 HDM 解码器的状态,并验证设备层次结构中每个端口的 CXL.mem 是否已启用. port0 参数为需要使能的 CXL PORT,对于 “options” 命令,其支持以下参数:

  • -e/–endpoint: 将端口参数从交换机端口标识符切换为终端端口标识符
  • -m/–enable-memdevs: 在启用端口后尝试启用下级内存设备. 请注意只有在其设备拓扑结构中的所有 CXL 端口都启用后,内存设备才会被启用
  • –debug: 打开额外的调试消息,包括库调试信息
# 查看 CXL ENDPOINT/PORT
cxl list -EP
# 使能 CXL SWITCH 下游端口的 CXL ENDPOINT
cxl enable-port -e endpoint3
# 使能 CXL PORT
cxl enable-port port2
# 查看结果
cxl list -EP

如何成功,则输出使能 CXL PORT 的数量;如果失败,则输出使能 CXL PORT 的数量为 0.

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

disable-port
cxl disable-port <port0> [<port1>..<portN>] [<options>]

enable-port 命令用于禁用/热拔一个或多个 CXL PORT, 通常情况下,在测试和调试场景中,禁用 CXL 端口及其依赖于该端口激活进行 CXL.mem 操作的任何内存设备. 对于 “options” 命令,其支持以下参数:

  • -e/–endpoint: 将端口参数从交换机端口标识符切换为终端端口标识符
  • -f/–force: 危险覆盖安全措施,即使工具检测到有子内存设备在活动使用中,也可尝试禁用端口. 请注意,CXL 内存范围可能由平台固件建立,禁用活动设备类似于从运行的系统中强制移除内存
  • –debug: 打开额外的调试消息,包括库调试信息
# 查看 CXL ENDPOINT/PORT
cxl list -EP
# 禁止 CXL SWITCH 下游端口的 CXL ENDPOINT
cxl disable-port -e endpoint3
# 禁止 CXL PORT
cxl disable-port port2
# 查看结果
cxl list -EP

如果成功,则输出禁止 CXL PORT 的数量;如果失败,则输出禁止 CXL PORT 的数量为 0.

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