背景:
操作dpdk的过程肯定会设计到网卡的绑定。本人最常用的网卡绑定方式是uio模式,即运行在用户空间的I/O技术。Linux系统中一般的驱动设备都是运行在内核空间,而在用户空间用应用程序调用即可。但是这种方式与kernel密切相关,无法做到dpdk打包与系统内核无关化。故而谋求最安全的vfio方式来绑定网卡。
要求:
通过vfio方式绑定网卡,取消uio加载.ko等与内核版本相关的操作。
操作实践:
1:如何确定cpu是否支持硬件虚拟化(VT-d)
命令如下:
egrep '(vmx|svm)' /proc/cpuinfo
无输出内容即为不支持。相反则支持 – 但是您仍需要确定在 BIOS 中是否启用了该虚拟化技术。 如果返回 SVM 旗帜标志,则表示您的处理器支持 AMD-V。而返回 VMX 旗帜标志,则表示您的处理器支持 INTEL-VT
2:
3:dmesg | grep DMAR 如果有内容输出,并可以看到 DMAR-IR: Enabled IRQ remapping in x2apic mode的数据,说明开启了,没有的话需要到bios中是能虚拟化功能(vt-d)。
没有内容输出的话可以执行下面命令通过非安全的方式绑定网卡:echo Y | tee /sys/module/vfio/parameters/enable_unsafe_noiommu_mode即可执行步骤6及以后的操作
4:reboot
5:cat /proc/cmdline 如果可以看到添加的势能信息,即使能成功。
6:modprobe vfio-pci
7:python usertools/dpdk-devbind.py --bind=igb 05:00.0
出现的问题:
1:在/etc/default/grub中添加 iommu=pt intel_iommu=on 重新编译 (grub2-mkconfig -o /boot/grub2/grub.cfg) 内核,查看是否使能inter_iommu(cat /proc/cmdline)看不到添加的内容,说明是能失败,看到即ok,到此为止。
解决方案: 在根目录中查找cat /proc/cmdline出来的内容, (例如:grep -r 'root=/dev/mapper/centos-root')发现有grub.cfg文件如下:
boot/efi/EFI/centos/grub.cfg
boot/grub2/grub.cfg
上面这两个有一个是可以看到添加的内容的。另一个看不到添加的内容。
直接打开看不到内容的文件,找到与kernel版本号对应的位置将 iommu=pt intel_iommu=on 添加进去即可。然后reboot重启
2:1能操作的前提是:
硬件支持虚拟化
系统开启了虚拟化
#!/bin/bash #Auth:Wangfei #单位:NDSC if [[ $# -eq 0 ]];then eth1=eno4; eth2=eno4; elif [[ $# -eq 1 ]];then eth1=$1; elif [[ $# -eq 2 ]];then eth1=$1; eth2=$2; fi set_huge(){ mkdir -p /mnt/huge echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages if [[ $? -ne 0 ]];then echo "hugepages set failed"; exit 1; fi mount -t hugetlbfs nodev /mnt/huge if [[ $? -ne 0 ]]; then echo "huge node mount faied"; exit 1; fi echo 0 > /proc/sys/kernel/randomize_va_space if [[ $? -ne 0 ]]; then echo "randomize_va_space set failed "; exit 1; fi } environment_check(){ #should make sure the hardware support the vt-d or the iommu and the vt-d or the iommu enable #hardware support HARDWARESUPPORT=`egrep '(vmx|svm)' /proc/cpuinfo` if [[ -z $HARDWARESUPPORT ]];then echo "hardware not support vt-d ot iommu"; exit 1; fi modprobe vfio-pci if [[ $? -ne 0 ]];then echo "mount vfio-pci failed"; exit 1; fi #insmod /usr/lib/modules/4.15.0/extra/dpdk/rte_kni.ko carrier=on #/lib/modules/3.10.0-1160.24.1.el7.x86_64/extra/dpdk/rte_kni.ko carrier=on python /usr/local/share/dpdk/usertools/dpdk-devbind.py --status ifconfig $eth1 down ifconfig $eth2 down #ENABLE=`dmesg | grep DMAR` ENABLE=`dmesg | grep 'Enabled IRQ'` if [[ -z $ENABLE ]];then echo Y | tee /sys/module/vfio/parameters/enable_unsafe_noiommu_mode #echo "虚拟化功能没使能"; #exit 1; fi } bind_vfio(){ #insmod /usr/lib/modules/4.15.0/extra/dpdk/igb_uio.ko #/lib/modules/3.10.0-1160.24.1.el7.x86_64/extra/dpdk/igb_uio.ko python /usr/local/share/dpdk/usertools/dpdk-devbind.py --bind=vfio-pci $eth1 if [[ $? -ne 0 ]];then echo "bind $eth1 command failed "; exit 1; fi BINDNET1OK=`ip -a | grep $eth1` if [[ $BINDNET1OK -ne 0 ]];then echo "$eth1 bind failed"; exit 1; fi python /usr/local/share/dpdk/usertools/dpdk-devbind.py --bind=vfio-pci $eth2 if [[ $? -ne 0 ]];then echo "bind $eth2 command failed "; exit 1; fi BINDNET2OK=`ip -a | grep $eth2` if [[ $BINDNET2OK -ne 0 ]];then echo "$eth2 bind failed"; exit 1; fi } #export FF_PATH=/usr/local/lib #export FF_DPDK=/usr/local/share/dpdk/x86_64-native-linuxapp-gcc start(){ /usr/local/nginx_fstack/sbin/nginx -c /usr/local/nginx_fstack/conf/nginx.conf if [[ $? -ne 0 ]];then echo "nginx start failed "; cat /usr/local/nginx_fstack/logs/error.log | tail -n 100 exit 1; fi } deploy(){ source /etc/profile set_huge environment_check bind_vfio } deploy
参考:
https://juejin.cn/post/6906503826531385357
https://blog.csdn.net/linggang_123/article/details/114394339