DPDK开发杂记

注意,本文的示例是基于Linux x86_64环境。如果你的环境不一样,应当将文中的x86_64-native-linuxapp-gcc 换成实际的值。
例如,32位linux环境,则换成i686-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应用程序运行前,需要通过一序列命令准备运行环境。
可以将相关命令写到 ~/run_dpdk_prepair.sh 中,以方便运行。
run_dpdk_prepair.sh示例内容如下。


[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

注意:dpdk程序中,端口的编号(即portid)从0开始。
portid与物理口的对应关系为:物理口按pci总线地址排序,地址越小,portid就越小。


项目makefile的修改

使用dpdk库的项目,无须将makefile修改为dpdk自带的应用程序的makefile风格,可以继续使用项目自己的makefile。
但是,需要对项目的makefile做出如下修改。


编译选项,增加如下内容。

-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   


升级Linux内核

对于高于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"


2. 修改dpdk源码,让虚拟网卡能够收发包。
注意,这是个独立问题,和前一问题没有联系。
修改lib/librte_eal/linuxapp/igb_uio/igb_uio.c中igbuio_pci_probe函数(如果是dpdk-2.2.0的话,就是第509行)的一条if语句的判断条件,一共就一行代码。

        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;
                }


你可能感兴趣的:(dpdk)