目录
Centos7安装DPDK
1系统准备工作
1.1查看Linux机器是否为NUMA结构
1.2大页内存的挂载和分配
1.3加载启动dpdk需要的uio功能
1.4网络端口绑定和解绑定到内核驱动模块
2.安装依赖包
3.解压与编译运行
4.问题与解决方法
4.1make: *** /lib/modules/3.10.0-229.el7.x86_64/build: 没有那个文件或目录
4.2fatal error: numa.h: No such file or directory
4.3提示 初始值设定项里有未知的字段‘ndo_change_mtu’
5.快速构建
Centos7安装DPDK
背景环境:
CentOS7.6
1系统准备工作
1.1查看Linux机器是否为NUMA结构
Redhat 或者Centos系统中可以通过命令# grep -i numa /var/log/dmesg 查看输出结果:
如果输出结果为:No NUMA configuration found,说明numa为disable,如果不是上面的内容说明numa为enable。下图则表示该机器为NUMA结构。一般我们见到的Linux服务器都是NUMA结构。
1.2大页内存的挂载和分配
在NUMA设备中,分配应该明确指定在哪个节点上:
echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
一旦预留了hugepage内存,为了使内存可用于DPDK,请执行以下步骤:
mkdir /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
通过将一下命令添加到 /etc/fstab 文件中,安装点可以在重启时永久保存:
nodev /mnt/huge hugetlbfs defaults 0 0
1.3加载启动dpdk需要的uio功能
要运行任何的DPDK应用程序,需要将合适的uio模块线加载到当前内核中。在多数情况下,Linux内核包含了标准的 uio_pci_generic 模块就可以提供uio能力。 该模块可以使用命令加载
sudo modprobe uio_pci_generic
区别于 uio_pci_generic ,DPDK提供了一个igb_uio模块(可以在kmod目录下找到)。可以通过如下方式加载:
sudo modprobe uio
sudo insmod kmod/igb_uio.ko
Note
对于一下不支持传统中断的设备,例如虚拟功能(VF)设备,必须使用 igb_uio 来替代 uio_pci_generic 模块。
由于DPDK 1.7版本提供VFIO支持,所以,对于支持VFIO的平台,可选则UIO,也可以不用。
加载vfio模块:
sudo modprobe vfio-pci
1.4网络端口绑定和解绑定到内核驱动模块
从版本1.4开始,DPDK应用程序不再自动解除所有网络端口与原先内核驱动模块的绑定关系。 相反的,DPDK程序在运行前,需要将所要使用的端口绑定到 uio_pci_generic, igb_uio 或 vfio-pci 模块上。 任何Linux内核本身控制的端口无法被DPDK PMD驱动所使用。
默认情况下,DPDK将在启动时不再自动解绑定内核模块与端口的关系。DPDK应用程序使用的任何端口必须与Linux无关,并绑定到 uio_pci_generic, igb_uio 或 vfio-pci 模块上。
端口从Linux内核解绑,然后绑定到 uio_pci_generic, igb_uio 或 vfio-pci 模块上供DPDK使用,可以使用脚本dpdk_nic _bind.py(位于usertools目录下)。 这个工具可以用于提供当前系统上网络接口的状态图,绑定或解绑定来自不同内核模块的接口。请注意,要将接口绑定到uio或vfio的话,需要先将这两个模块加载到内核,再运行 dpdk-devbind.py 脚本。
对于网卡的绑定和解绑定,都需要root权限
./usertools/dpdk-devbind.py –status
绑定设备 eth1,``04:00.1``, 到 uio_pci_generic 驱动:
./usertools/dpdk-devbind.py --bind=uio_pci_generic 04:00.1
或者
./usertools/dpdk-devbind.py --bind=uio_pci_generic eth1
恢复设备 82:00.0 到Linux内核绑定状态:
./usertools/dpdk-devbind.py --bind=ixgbe 82:00.0
2.安装依赖包
yum install libpcap libpcap-devel
yum install pciutils
yum install –y kernel-devel kernel-headers
yum install kernel.x86_64 -y
yum install net-tools.x86_64
3.解压与编译运行
tar -xzvf dpdk-17.05.tar.gz
cd dpdk-17.05
make config T=x86_64-native-linuxapp-gcc
sed -ri 's,(PMD_PCAP=).*,\1y,' build/.config
make
// 以上操作仅仅是解决编译问题
// 如果需要使用dpdk来编译运行对应的程序的话,还需要在/etc/profile里面(或者~/bashrc)加入环境变量
export RTE_SDK=/home/yml/dpdk/dpdk-stable-16.07.2 //这个是你生成的编译环境的路径
export RTE_TARGET=x86_64-native-linuxapp-gcc //编译的环境变量
export DESTDIR = /home/yml/dpdk/dpdk-stable-16.07.2/ //你的安装路径,就是编译出来的文件的路径
make install T=$RTE_TARGET
// 接下来就可以编译运行一个简单程序
cd examples/helloworld/
make
运行一个简单程序
UIO驱动和hugepage必须在程序运行前设置好。
将DPDK应用程序二进制文件拷贝到目标设备,按照如下命令运行(我们假设每个平台处理器有4个内存通道,并且存在core0~3用于运行程序):
[root@compute build]# ./helloworld -c f -n 4
此时会提示如下错误:
EAL: Detected 24 lcore(s)
EAL: No free hugepages reported in hugepages-1048576kB
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: Can only reserve 330 pages from 1088 requested
Current CONFIG_RTE_MAX_MEMSEG=256 is not enough
Please either increase it or request less amount of memory.
EAL: FATAL: Cannot init memory
EAL: Cannot init memory
PANIC in main():
Cannot init EAL
5: [./helloworld() [0x442236]]
4: [/lib64/libc.so.6(__libc_start_main+0xf5) [0x7f4a9bfe6505]]
3: [./helloworld() [0x43fa48]]
2: [./helloworld(__rte_panic+0xb8) [0x43a38e]]
1: [./helloworld(rte_dump_stack+0x1a) [0x47dcea]]
Aborted (core dumped)
有可能是服务器上有别的进程在使用大页内存,此时可以在命令行后接上—socket-mem限制hugepage分配的内存大小。
4.问题与解决方法
4.1make: *** /lib/modules/3.10.0-229.el7.x86_64/build: 没有那个文件或目录
错误信息:
make -C /lib/modules/3.10.0-229.el7.x86_64/build M=/home/kpatch/kmod/core kpatch.ko
make: Entering an unknown directory
make: *** /lib/modules/3.10.0-229.el7.x86_64/build: 没有那个文件或目录。 停止。
make: Leaving an unknown directory
make[2]: *** [kpatch.ko] 错误 2
make[2]: Leaving directory `/home/kpatch/kmod/core'
make[1]: *** [all] 错误 2
make[1]: Leaving directory `/home/kpatch/kmod'
make: *** [build-kmod] 错误 2
解决思路:
- 进入/usr/src/kernels/下看有没有相应的内核开发包,没有,就安装,若有跳过第一步。如果有,但是内核开发包的版本号比现有内核高。该情况如下截图:
没关系,我们先执行第一步。
UNAME=$(uname -r)
yum install gcc kernel-devel-${UNAME%.*}
执行完成这一步之后,我们查看一下回显信息,即使是如下情况,也没关系,继续按部就班地处理
2. 进入/lib/modules/3.10.0-229.el7.x86_64,创建软连接,要注意的是在modules目录下,是有一个和当前版本号完全一致的路径的,但是/usr/src/kernerls可能不一致。创建相应的软连接
使用如下命令创建软连接
ln -s /usr/src/kernels/3.10.0-1062.el7.x86_64/ /lib/modules/3.10.0-229.el7.x86_64/build
如果提示build文件已经存在,就rm该文件再创建软连接。值得注意的是,这里就算两个内核的版本号不一致,创建软连接也是ok的,这样做带来的问题以及解决方案会在下文中提及。
4.2fatal error: numa.h: No such file or directory
解决方法:yum install numactl-devel*x86_64
4.3提示 初始值设定项里有未知的字段‘ndo_change_mtu’
这个问题,其实是由于3.1的软连接的实际文件/目录的内核版本号不一致导致的,新版本的内核文件对该字段进行了修改。解决方法如下
用find / -name netdevice.h 查找内核中的头文件,找到struct net_device_ops 中的 ndo_change_mtu,
会看到ndo_change_mtu被替换成对应版本的ndo_change_mtu_rhXX,比如 ndo_change_mtu_rh74 将 /kni_net.c:704:2 中 ndo_change_mtu 用 ndo_change_mtu_rh74
重新编译后不再报错。
5.快速构建
可以使用脚本进行快速构建
dpdk-setup.sh