4. DPU存储卸载配置
任务目标
在DPU(以NVIDIA BlueField-2为例)上启用NVMe-oF(NVMe over Fabrics)存储协议卸载,使主机CPU不再参与远程存储的数据通路处理,从而降低CPU占用并加速远程存储访问。完成本案例后,主机将能够通过DPU上的卸载路径访问远端NVMe存储设备。
环境依赖
- 硬件:NVIDIA BlueField-2 DPU(或兼容的BlueField系列),x86主机通过PCIe连接DPU
- 软件:DOCA 2.x(含doca-nvmeof工具)、MLNX_OFED驱动、Linux内核≥5.15(支持nvme-tcp卸载)
- 远端存储:支持NVMe-oF TCP的存储阵列或Linux服务器(运行nvmet)
实现原理
DPU存储卸载的核心是将NVMe-oF的TCP处理从主机卸载到DPU的ARM核与硬件加速引擎。主机侧仅暴露标准NVMe块设备,数据路径为:主机→PCIe→DPU硬件加速→网络→远端存储,主机CPU不参与TCP/IP协议栈与NVMe命令封装。
关键完整代码
以下脚本在DPU的ARM系统上执行,完成NVMe-oF卸载配置。该脚本创建本地子系统、添加远端存储作为命名空间,并通过DPU硬件加速导出为NVMe设备。
#!/bin/bash
# dpu_nvmeof_unload_config.sh
# 在DPU ARM系统上运行,需root权限
set -e
# 配置参数
REMOTE_IP="192.168.100.10" # 远端NVMe-oF目标IP
REMOTE_NQN="nqn.2024-01.com.test:storage1" # 远端目标NQN
LOCAL_NQN="nqn.2024-01.com.test:dpu-unload" # 本地子系统NQN
LOCAL_IP="192.168.100.20" # DPU用于存储流量的IP
# 1. 加载NVMe-oF相关模块
modprobe nvme-tcp
modprobe nvmet
modprobe nvmet-tcp
# 2. 创建本地NVMe子系统
mkdir -p /sys/kernel/config/nvmet/subsystems/${LOCAL_NQN}
echo 1 > /sys/kernel/config/nvmet/subsystems/${LOCAL_NQN}/attr_allow_any_host
# 3. 创建命名空间并关联远端存储
# 先连接远端NVMe-oF目标,获取本地设备名
nvme connect -t tcp -n ${REMOTE_NQN} -a ${REMOTE_IP} -s 4420
sleep 2
REMOTE_DEV=$(nvme list | grep "${REMOTE_NQN}" | awk '{print $1}' | head -1)
if [ -z "${REMOTE_DEV}" ]; then
echo "ERROR: 无法连接远端存储 ${REMOTE_NQN}"
exit 1
fi
# 4. 将远端设备作为命名空间添加到本地子系统
mkdir -p /sys/kernel/config/nvmet/subsystems/${LOCAL_NQN}/namespaces/1
echo -n "${REMOTE_DEV}" > /sys/kernel/config/nvmet/subsystems/${LOCAL_NQN}/namespaces/1/device_path
echo 1 > /sys/kernel/config/nvmet/subsystems/${LOCAL_NQN}/namespaces/1/enable
# 5. 配置TCP端口并启用卸载
mkdir -p /sys/kernel/config/nvmet/ports/1
echo "${LOCAL_IP}" > /sys/kernel/config/nvmet/ports/1/addr_traddr
echo "tcp" > /sys/kernel/config/nvmet/ports/1/addr_trtype
echo "4420" > /sys/kernel/config/nvmet/ports/1/addr_trsvcid
echo "ipv4" > /sys/kernel/config/nvmet/ports/1/addr_adrfam
# 关联子系统到端口
ln -s /sys/kernel/config/nvmet/subsystems/${LOCAL_NQN} \
/sys/kernel/config/nvmet/ports/1/subsystems/${LOCAL_NQN}
# 6. 启用硬件加速卸载(关键步骤)
echo "mlx5_tcp" > /sys/kernel/config/nvmet/ports/1/offload_engine
# 7. 验证配置
echo "=== 本地子系统配置 ==="
cat /sys/kernel/config/nvmet/subsystems/${LOCAL_NQN}/namespaces/1/device_path
echo ""
echo "=== 端口卸载引擎 ==="
cat /sys/kernel/config/nvmet/ports/1/offload_engine
echo ""
echo "=== 主机侧发现的NVMe设备 ==="
nvme list
运行与验证
执行步骤:
- 将脚本复制到DPU的ARM系统(如/opt/scripts/),执行
chmod +x dpu_nvmeof_unload_config.sh - 以root运行:
./dpu_nvmeof_unload_config.sh - 在主机侧(x86)执行
nvme discover -t tcp -a <DPU_IP> -s 4420,应能看到本地子系统NQN - 主机侧连接:
nvme connect -t tcp -n ${LOCAL_NQN} -a <DPU_IP> -s 4420
通过条件:
- 脚本无错误输出,最后
nvme list显示远端设备已连接 - 主机侧
lsblk出现新的NVMe块设备(如/dev/nvme0n1) - 在主机上执行
dd if=/dev/zero of=/dev/nvme0n1 bs=1M count=100 oflag=direct无I/O错误 - 执行
cat /sys/kernel/config/nvmet/ports/1/offload_engine输出为mlx5_tcp,确认卸载已启用
常见问题
- 远端连接失败:确认远端存储的NVMe-oF目标已配置且网络可达(
ping ${REMOTE_IP}) - 卸载引擎设置失败:确认DPU固件版本支持NVMe-oF硬件卸载,执行
mlxup -q检查固件 - 主机无法发现设备:检查DPU上防火墙(
iptables -L)是否放行4420端口