1. DPDK环境搭建与Hugepage配置
任务目标
在Linux服务器上完成DPDK环境搭建,配置2MB和1GB两种Hugepage,并通过DPDK自带的工具验证大页内存分配成功。本案例以Ubuntu 22.04 + DPDK 22.11 LTS为基准环境。
环境依赖
- Linux内核 ≥ 5.4(建议Ubuntu 22.04+)
- gcc、make、pkg-config、libnuma-dev
- DPDK 22.11 LTS源码包(
dpdk-22.11.tar.xz) - root权限(大页配置与DPDK初始化必需)
实现步骤与代码
1. 安装依赖并编译DPDK
# 安装编译依赖
apt update && apt install -y build-essential pkg-config libnuma-dev python3-pip
pip3 install pyelftools
# 下载并解压DPDK
wget https://fast.dpdk.org/rel/dpdk-22.11.tar.xz
tar -xf dpdk-22.11.tar.xz && cd dpdk-22.11
# 配置并编译(仅构建库和工具,不编译内核模块)
meson setup build -Dexamples=helloworld -Dtests=false
ninja -C build
ninja -C build install
ldconfig
2. 配置Hugepage(2MB + 1GB)
#!/bin/bash
# 该脚本需以root运行:sudo ./setup_hugepages.sh
# 预留1GB大页内存池(4个1GB页)
echo 4 > /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
# 预留2MB大页(1024个2MB页,共2GB)
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
# 挂载hugetlbfs(若未挂载)
mkdir -p /mnt/huge_1G /mnt/huge_2M
mount -t hugetlbfs -o pagesize=1G none /mnt/huge_1G
mount -t hugetlbfs -o pagesize=2M none /mnt/huge_2M
# 验证配置结果
grep -i hugepages /proc/meminfo
ls /sys/kernel/mm/hugepages/
3. 绑定网卡并运行验证程序
# 查看网卡PCI地址(示例:0000:03:00.0)
dpdk-devbind.py --status
# 将网卡绑定到vfio-pci驱动(需先加载模块)
modprobe vfio-pci
dpdk-devbind.py --bind=vfio-pci 0000:03:00.0
# 运行helloworld验证DPDK初始化与大页分配
cd /path/to/dpdk-22.11/build/examples
./dpdk-helloworld -l 0-1 -a 0000:03:00.0 --huge-dir=/mnt/huge_1G
验证方法与通过标准
- 大页配置验证:执行
grep -i hugepages /proc/meminfo,应看到HugePages_Total: 1028(1024个2MB页 + 4个1GB页),且HugePages_Free与Total相等。 - DPDK初始化验证:运行
dpdk-helloworld后,输出hello from core 0和hello from core 1即表示EAL初始化成功,大页内存分配正常。 - 内存分配验证:若程序启动时出现
EAL: No free hugepages reported,说明大页配置失败;正常启动时EAL日志会显示Memory: 2097152KB等已检测到的大页总量。
常见问题
- 1GB大页配置失败:确认CPU支持1GB页(
grep pdpe1gb /proc/cpuinfo),且BIOS中未禁用。若系统内存不足,减少nr_hugepages值。 - VFIO绑定失败:确保IOMMU已开启(内核参数
intel_iommu=on iommu=pt),或改用igb_uio模块。 - hugepage挂载点权限:运行DPDK程序的用户需对
/mnt/huge_*有读写权限,可chmod 777 /mnt/huge_*临时解决。
上图展示了DPDK通过EAL接口访问大页内存的完整路径:应用调用EAL初始化后,EAL通过mmap系统调用映射/mnt/huge_*挂载点下的文件,内核从预留的大页池中分配物理页并建立页表映射,最终返回用户态虚拟地址供DPDK直接访问。2MB页用于常规数据面缓冲,1GB页用于需要超大连续内存的场景(如硬件卸载或大表查找)。