4. CXL 内存设备在线与离线
任务说明
本案例通过 CXL 内存设备的 sysfs 接口,执行内存块的在线(online)与离线(offline)操作,观察内核内存热插拔行为。核心操作对象是 /sys/devices/system/memory/memoryN/ 下的 state 文件。
CXL 内存设备被内核识别后,会以 memory block 的形式注册到 /sys/devices/system/memory/。每个 block 对应一个 memoryN 目录,其 state 文件可读写:写入 online 或 offline 触发内存热插拔。
环境与依赖
- Linux 内核 5.19+,已启用
CONFIG_MEMORY_HOTPLUG与 CXL 相关配置 - 系统已识别到 CXL 内存设备(
daxctl或cxl list可见) - root 权限(写 sysfs 需要 CAP_SYS_ADMIN)
- Python 3.6+(仅用标准库)
操作流程
核心代码
以下脚本枚举所有 memory block,对指定 block 执行 offline 与 online,并在每步后回读 state 验证结果。
#!/usr/bin/env python3
"""CXL 内存设备在线/离线操作与验证"""
import os
import sys
MEM_BASE = "/sys/devices/system/memory"
def list_blocks():
"""返回所有 memoryN 目录名(按编号排序)"""
blocks = []
for name in os.listdir(MEM_BASE):
if name.startswith("memory") and name[6:].isdigit():
blocks.append(name)
return sorted(blocks, key=lambda n: int(n[6:]))
def read_state(block):
path = os.path.join(MEM_BASE, block, "state")
with open(path) as f:
return f.read().strip()
def write_state(block, value):
path = os.path.join(MEM_BASE, block, "state")
with open(path, "w") as f:
f.write(value)
def set_state(block, target):
"""切换状态并回读验证,返回 (成功, 实际状态)"""
before = read_state(block)
if before == target:
return True, before
try:
write_state(block, target)
except OSError as e:
return False, f"写入失败: {e}"
after = read_state(block)
return after == target, after
def main():
blocks = list_blocks()
if not blocks:
print("未发现 memory block,请确认内核已启用内存热插拔")
sys.exit(1)
print(f"发现 {len(blocks)} 个 memory block: {blocks[0]} .. {blocks[-1]}")
print(f"{'block':<12} {'初始':<10} {'offline后':<10} {'online后':<10}")
print("-" * 46)
for block in blocks:
init = read_state(block)
ok_off, after_off = set_state(block, "offline")
ok_on, after_on = set_state(block, "online")
flag = "OK" if (ok_off and ok_on) else "FAIL"
print(f"{block:<12} {init:<10} {after_off:<10} {after_on:<10} [{flag}]")
if __name__ == "__main__":
main()
运行方式
sudo python3 cxl_mem_online_offline.py
若只想操作单个 block,可手动执行:
# 查看当前状态
cat /sys/devices/system/memory/memory0/state
# 离线
echo offline | sudo tee /sys/devices/system/memory/memory0/state
# 在线
echo online | sudo tee /sys/devices/system/memory/memory0/state
验证方法与通过条件
- 脚本输出每个 block 的初始状态、offline 后状态、online 后状态。
- 通过条件:offline 后
state回读为offline,online 后回读为online,标记为[OK]。 - 若某 block 无法离线(如正在被使用),写入会返回
EBUSY,脚本标记[FAIL]并显示错误信息,属正常现象。 - 可同时用
dmesg | tail观察内核热插拔日志,确认Offlined memory block/Online memory block记录。
常见问题
- 写入返回 EBUSY:该内存块正在被使用(如内核数据结构、不可迁移页),无法离线。可尝试其他 block。
- state 文件不存在:内核未启用
CONFIG_MEMORY_HOTPLUG,或 CXL 设备未以内存设备模式注册。 - 权限不足:需 root 或 CAP_SYS_ADMIN 权限写入 sysfs。