注意,本文的示例是基于Linux x86_64环境。如果你的环境不一样,应当将文中的x86_64-native-linuxapp-gcc 换成实际的值。
DPDK环境变量
编译DPDK自带的应用程序,总是需要用到两个环境变量。
可以在 ~/.bash_profile中追加如下两行内容。
这样以后每次登陆,就会自动设置好。
export RTE_SDK=/opt/dpdk-2.2.0
export RTE_TARGET=x86_64-native-linuxapp-gcc
DPDK编译安装
dpdk的编译脚本很复杂。
以个人经验,最好通过如下一条命令完成。
那就是cd到dpdk源码目录,然后执行
make install T=x86_64-native-linuxapp-gcc DESTDIR=/usr/local
dpdk运行前的配置
dpdk应用程序运行前,需要通过一序列命令准备运行环境。[root@localhost dpdk-2.2.0]# cat ~/run_dpdk_prepair.sh
#!/bin/sh
bind_nic(){
ifconfig $1 down
${RTE_SDK}/tools/dpdk_nic_bind.py --bind=igb_uio $1
}
modprobe uio
insmod ${RTE_SDK}/${RTE_TARGET}/kmod/igb_uio.ko
echo 256 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
if [ ! -d /mnt/huge_page_fs ]; then
mkdir /mnt/huge_page_fs
fi
mount -t hugetlbfs none /mnt/huge_page_fs
bind_nic eth1
bind_nic eth2
-march=native -DRTE_CACHE_LINE_SIZE=64\
-I/usr/local/include/dpdk/ -include rte_config.h
-L/usr/local/lib -Wl,--whole-archive \
-lrte_distributor -lrte_reorder -lrte_pipeline -lrte_table -lrte_port \
-lrte_timer -lrte_hash -lrte_jobstats -lrte_lpm -lrte_power \
-lrte_acl -lrte_meter -lrte_sched -lm -lrt -lrte_vhost \
-Wl,--start-group -lrte_kvargs -lrte_mbuf -lrte_mbuf_offload -lrte_ip_frag \
-lethdev -lrte_cryptodev -lrte_mempool -lrte_ring -lrte_eal \
-lrte_cmdline -lrte_cfgfile -lrte_pmd_bond -lrte_pmd_vmxnet3_uio \
-lrte_pmd_virtio -lrte_pmd_cxgbe -lrte_pmd_enic -lrte_pmd_i40e \
-lrte_pmd_fm10k -lrte_pmd_ixgbe -lrte_pmd_e1000 \
-lrte_pmd_ring -lrte_pmd_af_packet -lrte_pmd_null -lrt -lm -ldl \
-Wl,--end-group -Wl,--no-whole-archive
对于高于dpdk-2.2.0的dpdk版本,使用2.6.32及更低版本的Linux内核可能是不行的。故障现象是,无法绑定网卡到igb_uio驱动。
实际测试发现,2.6.38及以上的内核是可以的。
注意,升级内核后,需要重新编译dpdk。因为igb_uio的编译是依赖于内核的。
内核升级的方法可以参考:http://blog.csdn.net/crazycoder8848/article/details/44131735
VMware虚拟机相关
1. 虚拟机网卡类型不是dpdk支持的类型
例如,在32位centos 6.5中,通过ethtool -i eth3查看网卡类型,发现driver是pcnet32。
那就需要修改虚拟机配置文件,文件名为 虚拟机名称.vmx。例如,共有4块网卡,都想换成dpdk支持的e1000类型。
那就增加如下内容即可。
ethernet0.virtualDev = "e1000"
ethernet1.virtualDev = "e1000"
ethernet2.virtualDev = "e1000"
ethernet3.virtualDev = "e1000"
case RTE_INTR_MODE_LEGACY:
if (pci_intx_mask_supported(dev)) {
dev_dbg(&dev->dev, "using INTX");
udev->info.irq_flags = IRQF_SHARED;
udev->info.irq = dev->irq;
udev->mode = RTE_INTR_MODE_LEGACY;
break;
}
case RTE_INTR_MODE_LEGACY:
if (pci_intx_mask_supported(dev) || !pci_intx_mask_supported(dev) ) {
dev_dbg(&dev->dev, "using INTX");
udev->info.irq_flags = IRQF_SHARED;
udev->info.irq = dev->irq;
udev->mode = RTE_INTR_MODE_LEGACY;
break;
}