DPDK的Ubuntu16.04版本安装全教程,包括遇到问题解决和helloworld例子测试等,另附分配大页和绑定网卡驱动脚本
环境搭建:虚拟机的CPU数量不能超过真实的机器,因此暂时无法模拟出NUMA的环境;dpdk需要至少两块网卡,eth0和eth1用于dpdk使用,eth2用于跟主机通信;打开虚拟机的配置文件, xxx.vmx,把所有网卡都设置成e1000ethernet0.present = "TRUE"ethernet0.connectionType = "hostonly"eth...
环境搭建:
虚拟机的CPU数量不能超过真实的机器,因此暂时无法模拟出NUMA的环境;
dpdk需要至少两块网卡,eth0和eth1用于dpdk使用,eth2用于跟主机通信;
打开虚拟机的配置文件, xxx.vmx,把所有网卡都设置成e1000
ethernet0.present = "TRUE"
ethernet0.connectionType = "hostonly"
ethernet0.wakeOnPcktRcv = "FALSE"
ethernet0.addressType = "static"
ethernet0.virtualDev = "e1000"
ethernet1.present = "TRUE"
ethernet1.connectionType = "hostonly"
ethernet1.wakeOnPcktRcv = "FALSE"
ethernet1.addressType = "static"
ethernet1.virtualDev = "e1000"
ethernet2.present = "TRUE"
ethernet2.connectionType = "nat"
ethernet2.wakeOnPcktRcv = "FALSE"
ethernet2.addressType = "static"
ethernet2.virtualDev = "e1000"
DPDK是因特尔推出的数据平面开发组件,主要是提供了一个高效的用户态网卡驱动,改以往网卡驱动采用的中断方式,为绑定线程轮询网卡的高效模式,可以大幅提高吞吐率。DPDK最新版的压缩包可以去官网下载,http://dpdk.org/download. 我这里用的环境是ubuntu16.04,DPDK版本是16.11.1
在安装DPDK之前我们需要安装另一个linux下另一个跟网络数据包相关的函数库——libpcap,命令行抓包软件tcpdump也是基于这个库实现的。
1. 安装libpcap
去官网 http://www.tcpdump.org/#latest-releases 下载libpcap的压缩包。我下的是libpcap-1.8.1.
先安装依赖库m4、bison、flex:
sudo apt-get install m4 bison flex
在特权用户下,安装libpcap:
cd libpcap-1.8.1
./configure
make
make install
安装成功,但是后面安装DPDK的时候却提示找不到libpcap.so.1,因为libpcap.so.1默认安装到了/usr/local/lib下,我们做一个符号链接到/usr/lib/下即可。
sudo ln -s /usr/local/lib/libpcap.so.1 /usr/lib/libpcap.so.1
2. 安装DPDK
将压缩包解压缩,按照下面的步骤安装:
tar xJf dpdk-<version>.tar.xz
cd dpdk-<version>
注意,以下操作中有些涉及特权级的,如果operation denied,加上sudo即可
2.1. 配置并编译DPDK,架构为64位x86linux系统,gcc编译
make install T=x86_64-native-linux-gcc
make
编译.png
编译过程如上图所示,其中如果有错,多数是由于依赖项,安装上依赖项就可以了。安装过程中我出现了如下问题:
numa.h: 没有那个文件或目录 #include <numa.h>
这是因为你没有安装libnuma,只要执行如下命令再重新安装即可:
CentOS: yum install libnuma-devel
Ubuntu: apt-get install libnuma-dev
2.2. 预配置大页存储
挂载了一个NUMA节点node0,最后一句命令的意思是在node0上预留了64个2MB的大页,即64*2048kB=128MB的内存
mkdir -p /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
echo 64 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
可能会遇到" echo "This is testPage." >/usr/local/nginx/html/index.html命令的时候,提示权限不够"的问题。
虽然知道echo命令是属于root用户的权限,但是我之前一直以为加个sudo就能够获取到root的全部权限,现在才发现这是不对的。使用sudo命令后,获取到的只是root的一部分权限。
解决办法:
1、直接使用root用户,这样肯定不会有问题;
2、具体实现如下:
sudo sh -c 'echo "This is testPage." >/usr/local/nginx/html/index.html'
查看网卡信息
ifconfig
网卡信息.png
从图中看出,两个网卡分别为enp3s0和wlp2s0。
2.3. 加载模块和绑定网卡
ifconfig enp3s0 down//先把有线网卡关掉,不然下一步会报错的。
modprobe uio
insmod build/kmod/igb_uio.ko//插入uio和igb_uio模块
这一步有可能会报错,不能插入该模块,网上查原因是因为linux 4.3.X以后的内核机制造成的,需要重启电脑进入bios,关闭secure boot即可。
加载igb uio模块还有可能会遇到如下问题:
ERROR: Target does not have the DPDK UIO Kernel Module. To fix, please try to rebuild target.
直接执行如下命令:sudo modprobe uio
python tools/dpdk-devbind.py --bind=igb_uio enp3s0//绑定igb_uio驱动到enp3s0
使用dpdk自带脚本查看状态
python tools/dpdk-devbind.py --status
网卡绑定.png
从图中可以看到0000:03:00.0网卡绑定的是igb_uio驱动,网卡绑定成功。
由于每次运行DPDK都需要分配大页和绑定网卡驱动,很麻烦,可以编写一个shell脚本,每次运行直接配置完成。
脚本内容如下:
#!/bin/bash
DEVICE="enp3s0"
DRIVER="igb_uio"
while getopts ":hd:r:" optname
do
case "$optname" in
"h")
echo " `basename ${0}`:usage:[-d device_name] [-r driver_name]"
echo " where device_name can be one in: {enp3s0,wlp2s0},driver_name can be one in: {igb_uio,rte_kni}"
exit 1
;;
"d")
DEVICE=$OPTARG
;;
"r")
DRIVER=$OPTARG
;;
*)
# Should not occur
echo "Unknown error while processing options"
;;
esac
done
mkdir -p /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
echo 64 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
ifconfig $DEVICE down
modprobe uio
insmod build/kmod/$DRIVER.ko
./tools/dpdk-devbind.py --bind=$DRIVER $DEVICE
另外,再写一个类似的反向的脚本,如果想要将网卡恢复正常驱动使用的时候可以恢复:
#!/bin/bash
DEVICE="0000:03:00.0"
DRIVER="alx"
while getopts ":hd:r:" optname
do
case "$optname" in
"h")
echo " `basename ${0}`:usage:[-d device_name] [-r driver_name]"
echo " where device_name can be one in: {0000:02:00.0,0000:03:00.0},driver_name can be one in: {alx,iwlwifi}"
exit 1
;;
"d")
DEVICE=$OPTARG
;;
"r")
DRIVER=$OPTARG
;;
*)
# Should not occur
echo "Unknown error while processing options"
;;
esac
done
./tools/dpdk-devbind.py --bind=$DRIVER $DEVICE
上面的网卡分别是enp3s0和wlp2s0,它们自身的驱动分别是alx和iwlwifi,根据实际修改。另外DPDK有些网卡是不支持的,需要去官网查看哪些网卡不支持。
运行如下图:
配置.png
恢复.png
3. 运行示例程序:
注意,这里演示用的是pcap的vdev,所以不需要绑定网卡,不然会报错找不到设备。当然vdev也可以按照官方教程里给的跑dpdk的vdev
./build/app/testpmd -c 7 -n 3 --vdev=eth_pcap0,iface=enp3s0 --vdev=eth_pcap1,iface=enp3s0 -- -i --nb-cores=2 --nb-ports=2 --total-num-mbufs=2048
//参数分别为-c <核数,二进制表示,7即111,三个核> -n<存储通道数> --vdev<虚拟设备名,自己给发包网卡起的名字>,iface<真实设备id> -- 端口数,buff数
运行截图:
示例程序运行1.png
在testpmd输入start开始转发流
示例程序运行2.png
输入stop,停止并显示这期间的流量。quit退出程序。
运行example/helloworld程序:注——也可以直接运行./helloworld
root@liuhy-VirtualBox:/home/liuhy/dpdk-stable-18.05.1/examples/helloworld/build# ./helloworld -c f
EAL: Detected 4 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Probing VFIO support...
EAL: PCI device 0000:00:03.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:08.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:09.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:0a.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100e net_e1000_em
hello from core 1
hello from core 2
hello from core 3
hello from core 0
可能会遇到如下问题:
遇见问题已放弃 (核心已转储):
这是因为手册中已经有说明:
下面的说明将允许在较旧的linux内核版本中以非根用户身份运行dpdk。但是,由于版本4.0,内核不允许非特权进程从pagemaps文件中读取物理地址信息,这使得这些进程无法使用需要物理地址的硬件设备。
转到root用户权限下运行即可。
更多推荐
所有评论(0)