一,安装相关依赖
1. 安装依赖
sudo apt update && sudo apt install -y \build-essential libnuma-dev meson ninja-build pciutils#安装Python3与PIP3
sudo apt install python3-pip
2. 升级 pip 和 setuptools
sudo apt install python3-pip python3-dev -y
python3 -m pip install --upgrade pip setuptools wheel
3. PIP3安装Meson与Ninjia,Meson负责构建项目依赖关系、Ninja进行编译
sudo pip3 install meson==0.53.2 ninja pwntools -i https://pypi.tuna.tsinghua.edu.cn/simple
二,绑定IGB_UIO驱动
虚拟机上DPDK无法绑定VFIO驱动,所以采用IGB_UIO驱动。UIO内核模块是内核提供的用户态驱动框架,而IGB_UIO是DPDK用于与UIO交互的内核模块,通过igb_uio来绑定指定的PCI网卡设备到DPDK使用。
1. 下载解压模块
正常来说可以通过git下载,但目前连接不到
sudo apt install git
git clone http://dpdk.org/git/dpdk-kmods
访问官网直接下载:https://git.dpdk.org/dpdk-kmods/commit/
解压:
tar xf dpdk-kmods-main.tar.xz
进入到IGB_UIO模块源码目录:
cd dpdk-kmods-main/linux/igb_uio/
2. 跳过检查
在虚拟机中添加的网卡,DPDK不支持,因此会出现EAL: Error enabling interrupts for fd 19报错,修改dpdk-kmods/linux/igb_uio/igb_uio.c中的代码,跳过DPDK PCI检查
// Original
pci_intx_mask_supported(udev->pdev)
// Change to
pci_intx_mask_supported(udev->pdev) || true
3. 编译模块
编译后,插入uio和igb_uio模块
make
sudo modprobe uio
sudo /sbin/insmod igb_uio.ko
验证模块安装正确
/sbin/lsmod | grep uio
三,DPDK安装
1. 安装DPDK 22.11
推荐版本DPDK 22.11
wget https://fast.dpdk.org/rel/dpdk-22.11.2.tar.xz
tar xf dpdk-22.11.2.tar.xz
cd dpdk-stable-22.11.2
# 编译并安装
meson build
ninja -C build
sudo ninja -C build install
sudo ldconfig
2.配置巨页
使用DPDK自带工具配置巨页:
-p 2M
指定大页内存的单页大小为 2MB(DPDK 支持 2MB 或 1GB 的大页)。
–setup 1G
设置大页内存的总大小为 1GB(脚本会自动计算所需的页数)。
# 配置巨页
sudo ./usertools/dpdk-hugepages.py -p 2M --setup 1G
# 巨页配置情况
sudo ./usertools/dpdk-hugepages.py -s
或者系统配置:
# 配置大页内存(每台VM)
echo "vm.nr_hugepages=2048" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
sudo mkdir -p /dev/hugepages
sudo mount -t hugetlbfs nodev /dev/hugepages
3. 网卡绑定DPDK
使用dpdk工具usertools/dpdk-devbind.py查看当前的网卡状态:ens33与ens34都处于活动状态,且目前仍采用Linux内核驱动
./usertools/dpdk-devbind.py --status
将ens33、ens37 down掉后,绑定DPDK
sudo ifconfig ens33 down
sudo ./usertools/dpdk-devbind.py --bind=igb_uio 0000:02:01.0sudo ifconfig ens37 down
sudo ./usertools/dpdk-devbind.py --bind=igb_uio 0000:02:05.0
查看网卡状态:网卡已通过igb_uio与dpdk绑定:
./usertools/dpdk-devbind.py --status
4. helloworld检查
在dpdk/build下编译example示例helloworld
cd build
meson configure -Dexamples=helloworld
ninja
在/dpdk/build/examples文件下运行helloworld例程
cd examples
sudo ./dpdk-helloworld
helloworld是一个简单的 DPDK(Data Plane Development Kit)示例程序,其主要功能是在每个工作逻辑核心(lcore)上启动一个函数 lcore_hello,并在主逻辑核心上也调用该函数。lcore_hello 函数的作用是打印出当前逻辑核心的 ID,以此展示如何在 DPDK 环境中在不同逻辑核心上运行代码。
/* Launch a function on lcore. 8< */
// 定义在逻辑核心上执行的函数
static int
lcore_hello(__rte_unused void *arg)
{// 定义一个无符号整数变量,用于存储当前逻辑核心的 IDunsigned lcore_id;// 获取当前逻辑核心的 IDlcore_id = rte_lcore_id();// 打印当前逻辑核心的 IDprintf("hello from core %u\n", lcore_id);// 函数返回 0,表示执行成功return 0;
}
/* >8 End of launching function on lcore. *//* Initialization of Environment Abstraction Layer (EAL). 8< */
// 主函数,程序的入口点
int
main(int argc, char **argv)
{// 定义一个整数变量,用于存储函数返回值int ret;// 定义一个无符号整数变量,用于存储逻辑核心的 IDunsigned lcore_id;// 初始化 DPDK 的环境抽象层(EAL)ret = rte_eal_init(argc, argv);// 检查 EAL 初始化是否失败if (ret < 0)// 如果失败,使用 rte_panic 函数输出错误信息并终止程序rte_panic("Cannot init EAL\n");/* >8 End of initialization of Environment Abstraction Layer *//* Launches the function on each lcore. 8< */// 遍历所有的工作逻辑核心RTE_LCORE_FOREACH_WORKER(lcore_id) {/* Simpler equivalent. 8< */// 在指定的逻辑核心上远程启动 lcore_hello 函数rte_eal_remote_launch(lcore_hello, NULL, lcore_id);/* >8 End of simpler equivalent. */}// 在主逻辑核心上调用 lcore_hello 函数lcore_hello(NULL);/* >8 End of launching the function on each lcore. */// 等待所有逻辑核心上的任务执行完毕rte_eal_mp_wait_lcore();// 清理 DPDK 的环境抽象层(EAL)rte_eal_cleanup();// 主函数返回 0,表示程序正常结束return 0;
}
根据输出可以看到,逻辑核心是0,工作核心是1-7