intel 82576网卡折腾-sr-iov使用
缘起
前段时间安装的openwrt虚拟机,网卡是基于螃蟹卡虚拟出来的,性能在一些高占用下可能会不稳定。
而intel的服务器网卡,能够通过网卡自带的虚拟化,在一个网卡硬件(pf)上,虚拟出很多的网卡(vf)出来,这些虚拟出来的网卡,每个都可以作为单独网卡使用,非常的方便,这个技术叫做SR-IOV,大家可以搜下技术资料,了解下pf、vf的概念。
因此就某鱼上淘了一张intel 82576的双口千兆网卡来,才65块钱,折腾搞起来~~~
折腾过程
0、不饶圈子,先说下这个intel82576的坑吧
这个82576网卡,在ubuntu server 18.04
系统下不用安装驱动,默认已经安装了intel的igb驱动,可以直接认。
坑:网线像是不通,路由器对应端口不亮
intel 82576网卡插上没反应,连不上网络。可能是这张intel网卡做了优化吧(为了省电?),如果没有在系统里声明了网卡物理接口(pf),那么就是像不通一样的。
即使使用ethtool测试,也都是未连接状态
ethtool enp4s0f1 如果是对vf,或者没有声明pf,则永远都是Link detected: no
需要做的是:在netplan里声明下这个物理接口
发现哪个网卡是pf,可以使用如下脚本
类似这个即是物理网卡 Virtual Functions on Intel Corporation 82576 Gigabit Network Connection. (enp4s0f1):
#!/bin/bash NIC_DIR="/sys/class/net" for i in $( ls $NIC_DIR) ; do if [ -d "${NIC_DIR}/$i/device" -a ! -L "${NIC_DIR}/$i/device/physfn" ]; then declare -a VF_PCI_BDF declare -a VF_INTERFACE k=0 for j in $( ls "${NIC_DIR}/$i/device" ) ; do if [[ "$j" == "virtfn"* ]]; then VF_PCI=$( readlink "${NIC_DIR}/$i/device/$j" | cut -d '/' -f2 ) VF_PCI_BDF[$k]=$VF_PCI #get the interface name for the VF at this PCI Address for iface in $( ls $NIC_DIR ); do link_dir=$( readlink ${NIC_DIR}/$iface ) if [[ "$link_dir" == *"$VF_PCI"* ]]; then VF_INTERFACE[$k]=$iface fi done ((k++)) fi done NUM_VFs=${#VF_PCI_BDF[@]} if [[ $NUM_VFs -gt 0 ]]; then #get the PF Device Description PF_PCI=$( readlink "${NIC_DIR}/$i/device" | cut -d '/' -f4 ) PF_VENDOR=$( lspci -vmmks $PF_PCI | grep ^Vendor | cut -f2) PF_NAME=$( lspci -vmmks $PF_PCI | grep ^Device | cut -f2). echo "Virtual Functions on $PF_VENDOR $PF_NAME ($i):" echo -e "PCI BDF\t\tInterface" echo -e "=======\t\t=========" for (( l = 0; l < $NUM_VFs; l++ )) ; do echo -e "${VF_PCI_BDF[$l]}\t${VF_INTERFACE[$l]}" done unset VF_PCI_BDF unset VF_INTERFACE echo " " fi fi done
坑:虚拟机不能直通vf
由于在某些主板下,所有的网卡,被分配到同一个iommu的分组里,而虚拟化硬件直通,需要把一个组的设备全部直通,因此不能单独直通一个vf,会报如下的错误。
intel Please ensure all devices within the iommu_group are bound to their vfio bus driver.
这个可以通过自己编译内核,增加acs override解决。
1、网卡插不上咋办,锯接口呗o( ̄︶ ̄)o
买来网卡,开心的拆开机箱准备开干,尴尬的一幕发生了,我的华擎j3455主板,居然tm没有pcie x4的接口,只有x1的接口,而新买的网卡是x4的,于是就插不上了。。。
本来已经准备在某宝买个转接卡了,因为一般pcie接口都是向下兼容的,比如显卡x16的,但是插在主板x8的接口上,依然是可以工作的。
然后不死心,又搜索了一番,发现网上的老哥思想真的活跃,居然可以把x1的接口锯开,直接插x4的网卡上去,真乃人才。。。
锯接口的过程是非常难搞的,我拿一把美工刀,硬是慢慢切下去了,花了有一上午,大家有角磨机的可以省很多功夫,另外,一定要精细些,不然搞断引脚那就彻底废了。
intel82576网卡不通?路由器上灯不亮
经过第一步的折腾,千辛万苦终于可以插上去了,发现一个诡异的事情,接口都是不通的,路由器灯不亮,像是没插线一样。
使用ethtool测试,也是未连接状态。
# 执行ethtool查看网卡状态 ethtool enp4s17f3 Settings for enp4s17f3: Supported ports: [ ] Supported link modes: 1000baseT/Full Supported pause frame use: No Supports auto-negotiation: No Supported FEC modes: Not reported Advertised link modes: 1000baseT/Full Advertised pause frame use: No Advertised auto-negotiation: No Advertised FEC modes: Not reported Speed: 1000Mb/s Duplex: Full Port: Other PHYAD: 0 Transceiver: internal Auto-negotiation: offCannot get wake-on-lan settings: Operation not permitted Current message level: 0x00000007 (7) drv probe link Link detected: no
这个问题,算是对于普通用户使用intel网卡的一个很大的坑,上面的坑里边已经讲了,经过几天的摸索,终于通过获取物理pf,然后将对应的网卡名称在netplan里进行声明解决了。
另外再说一点,对于intel 82576等支持sr-iov的网卡,都是需要先把pf启动起来(即在网卡声明里写上),然后才能使用各个vf的网卡的,包括在系统网卡声明里声明,已经直通给虚拟机,直接操作vf是不行的,完全没法用。
虚拟机直通
经过第一步的折腾,可以在宿主机里正常的使用pf、vf了,接下来就是虚拟机网卡直通了。
1、开启grub的iommu启动参数
使用如下命令开启:
sudo vi /etc/default/grub # GRUB_CMDLINE_LINUX_DEFAULT=里增加如下参数,记得参数末尾加空格 iommu=pt intel_iommu=on # update一下grub sudo update-grub2 sudo reboot
2、在虚拟机里增加虚拟网卡
可以通过virsh edit [虚拟机name]
编辑网卡,在devices
段中增加如下参数配置vf虚拟网卡。
<interface type='hostdev' managed='yes'> <mac address='33:33:00:33:33:33'/> <source> <address type='pci' domain='0x0000' bus='0x04' slot='0x11' function='0x5'/> </source> </interface>
其中这里的mac地址是设置直通的网卡的mac,可以随意设置。 这里的pci地址,可以使用之前的发现intel 网卡信息的脚本里找到。
Virtual Functions on Intel Corporation 82576 Gigabit Network Connection. (enp4s0f1): PCI BDF Interface======= ========= 0000:04:10.1 enp4s16f1 0000:04:10.3 enp4s16f3 0000:04:10.5 enp4s16f5 0000:04:10.7 enp4s16f7 0000:04:11.1 enp4s17f1 0000:04:11.3 enp4s17f3
比如要直通enp4s17f3
,这里的pc地址就分别是0000:04:11.3
保存退出后,shutdown然后在start虚拟机,就可以啦。
3、解决iommu分组问题导致的不能直通问题
由于内核对于安全性的考虑,导致在同一个pcie通道内的网卡,分组在了统一iommu组内,直通某一个就会报错。
这个问题可以通过自己编译内核解决,可以参考这个项目的方法进行。
补丁文件可以参考这里 https://gitlab.com/Queuecumber/linux-acs-override
操作方法可以参考这里 https://koolshare.cn/thread-166076-1-1.html
注意:这种方法是存在安全隐患的,切勿在公共虚拟化环境下使用
注意:这种方法是存在安全隐患的,切勿在公共虚拟化环境下使用
注意:这种方法是存在安全隐患的,切勿在公共虚拟化环境下使用
同时呢,由于我们是强行的拆解iommu的组,还需要修改下补丁的这一行,据说sata控制器直通存在问题,不建议这种方法直通,网卡应该是可以的。
把
+ if (!pci_is_pcie(dev) || + pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS))
改成
+ if (!pci_is_pcie(dev))
经过自行编译内核,然后安装后,使用如下命令开启内核,
sudo vi /etc/default/grub # GRUB_CMDLINE_LINUX_DEFAULT=里增加如下参数,记得参数末尾加空格 pcie_acs_override=downstream,multifunction # update一下grub sudo update-grub2 sudo reboot
4、openwrt安装intel vf驱动
由于默认情况下,openwrt没有按照igbvf的驱动,可以在openwrt里使用如下命令安装:
opkg updateopkg install kmod-igbvf
一些有用的命令和tips
# 查看网卡信息 lshw -c network -businfo # 查看iommu组信息 find /sys/kernel/iommu_groups/ -type l # 查看详细的iommu组信息 for d in /sys/kernel/iommu_groups/*/devices/*; do n=${d#*/iommu_groups/*}; n=${n%%/*}; printf 'IOMMU Group %s ' "$n"; lspci -nns "${d##*/}"; done; # 查看内核的iommu信息 dmesg |grep -i iommu
vf的使用,必须是对应的pf在线才能用起来,pf和vf只有pf在宿主内启用起来即在网络接口那里进行声明,可以不用绑定ip地址,只声明下就可以,然后vf可以直通给虚拟机作为普通网卡
由于虚拟出来的设备很多,需要辨别哪些pf、vf是插了网线的那个接口,建议使用文章开头的脚本来做
需要asc控制补丁才能单独设备分组,在iommu里分配设备直通到虚拟机
openwrt自带igb驱动,可以直接驱动intel 82576网卡,但是不能使用igbvf驱动宿主的vf虚拟网卡,需要安装 kmod-igbvf
pihole换了虚拟化vf的网卡后不能使用,是dns设置界面,默认是只监听其中一个网卡的,选择第三项,监听所有即可。
经过验证,是由于使用了intel网卡同一个网卡虚拟出的2个vf导致的问题,可能导致只监听一个网卡接口的设置下,判断不准导致其他客户端不能解析域名。
总结
整个折腾过程的坑非常的多,可能由于折腾的是专业的服务器领域的东西,好像资料也很少,整个过程非常的曲折。我一度以为这个网卡是坏的,我打磨的pcie 1接口是坏的。。。。 直到我切换到windows系统里,可以正常识别网卡。
生命在于折腾吧。。。另外总算知道了intel网卡sr-iov的用法了。即,宿主机绑定pf,然后虚拟机直通vf。中间的通信,通过宿主和虚拟机的驱动进行。
参考资料
https://yq.aliyun.com/articles/721471
https://gitlab.com/Queuecumber/linux-acs-override
https://heiko-sieger.info/iommu-groups-what-you-need-to-consider/
https://blog.acelan.idv.tw/2018/01/13/Build-Ubuntu-Kernel-on-PPA/
https://lkml.org/lkml/2013/5/30/513
https://koolshare.cn/thread-166076-3-1.html
https://www.reddit.com/r/VFIO/comments/8muu74/acs_patch_will_not_let_me_select_specific_devices/
https://software.intel.com/en-us/articles/configure-sr-iov-network-virtual-functions-in-linux-kvm
https://www.cnblogs.com/liuhongru/p/11068460.html
https://openwrt.org/packages/pkgdata/kmod-igbvf
已有3位网友发表了看法:
echo: write error: no such file or directory的办法:bios设置把pci ari support打开(在iommu一个页面)
发表评论