SR-IOV是Single Root I/O Virtualization的缩写。
在虚拟机中,一切皆虚拟。比如网卡,虚拟机看来好像有一个真实网卡,但是这个网卡是宿主机虚拟出来的硬件,也就是一堆软件代码而已,没有真实硬件。
虚拟虽然万能,但是很显然,这一堆代码是需要CPU去执行的!所以,虚拟设备的性能会随着宿主机的性能而改变,另外宿主机由于需要进行数据处理,时延等也产生了。
我们之前也提到过,VT-D这个功能可以将物理的PCI-e设备直接分配给虚拟机,让虚拟机直接控制硬件,那么就可以避开上述的问题。但是,虚拟机会独占这个直通的PCI-e设备,一台宿主机可能有成百上千个虚拟机,如果每个虚拟机都给直通一个PCI-e设备,比如网卡,那么该造什么样的主机?拥有100个物理网卡的主机?想象一下也是不太可能。
为了解决这个问题,Intel提出来SR-IOV这个东西。SR-IOV最初应用在网卡上。简单的说,就是一个物理网卡可以虚拟出来多个轻量化的PCI-e物理设备,从而可以分配给虚拟机使用。大概的框图如下:
SR-IOV是虚拟化的一个重要功能。启用SR-IOV的这个功能,将大大减轻宿主机的CPU负荷,提高网络性能,降低网络时延等。
废话少说,下面说一下我们怎么使用SR-IOV,以及SR-IOV的性能如何?
各种主流虚拟宿主机都支持SR-IOV。下面我们用VMware的ESXi平台来讲解。
SR-IOV需要软硬都支持才行。这次我们使用的硬件如下:
- SuperMICRO X9DRL-iF主版
- XEON E5 2687W 双CPU
- DDR3 ECC REG 128GB 内存
- Intel X540-T2双口万兆网卡
- 存储若干
首先需要在BIOS打开VT-D及SRIOV支持选项,这个不细说。接下来配置ESXi。
进入ESXi硬件配置页面,找到我们需要进行配置的SR-IOV网卡。
两个网口,我们配置第一个网口为SR-IOV口。
设置虚拟VF为8个。这个网卡每个网口最大支持64个VF。
保存配置之后,重新启动ESXi,就可以看到硬件上出现了8个虚拟网卡设备。这样子我们就完成了ESXi的SR-IOV配置。
小TIPS:初次玩这些东西时,最好选用可靠的服务器平台,这些服务器平台都是经过测试支持SR-IOV的。不要选用民用主板,要不然硬件这一部分你都搞不定,可能就放弃了。
接下来,SR-IOV的性能如何呢?我们对比一下看看。
测试时使用的网络拓扑如下:
两台主机,FreeBSD 12.0和ESXi的10G网口0直连。新建一台虚拟机,Port0中的SR-IOV VF0分配给VM使用。另外,PF设置连接虚拟交换机,然后再给VM分配一个虚拟网卡,连接这个虚拟交换机。
我们将流量跑不同的路径,就可以对比出来两者的性能差异。
下图是Windows8.1虚拟机中的网卡配置,Ethernet1是vmxnet3虚拟网卡,pciPassthru0是SR-IOV的网卡。
下面是虚拟机中的网卡界面。
测试工具使用iperf3。我们在FreeBSD中启动服务端。
虚拟机中,我们先把虚拟机中SR-IOV的VF网卡禁用,先测试虚拟网卡。
2.21Gbit/sec,哦?好像成绩不怎么好?
接下来禁用虚拟网卡,启用VF网卡。看一下VF的网卡的表现:
3.21Gbits/sec
第一轮VF网卡就已经胜出!3.21Gbits VS 2.21Gbits。另外我们也可以看出,虚拟网卡的流量不怎么稳定,最快3.05G, 最慢1.96G/sec。而VF网卡的性能就很稳定了。
不过怎么10G网卡才只有这么点性能?一般来说,单线程流量是喂不饱10G网络的。我们接下来用5个线程来看看。iperf可以通过参数-P 5打开5个线程。
先看虚拟网卡的情况:
不错!变成了8.68Gbits/sec!VF网卡呢?
9.57Gbits/sec!快达到10G网卡的上限了!
当然,10G网络相比较对于1G网络来说,调优非常关键。我们这次限于篇幅这次只用缺省的参数进行测试,不能算是一次严谨的对比。
但是抛开CPU占用等情况,VF网卡已经比虚拟网卡在速度上胜出了。
对于SR-IOV的支持,FreeBSD在系统层面已经完全支持。FreeBSD有一个叫作iovctl的命令,可以初始化及设置SR-IOV设备。
对于FreeBSD下SR-IOV感兴趣的同学,可以参考下面的PPT。
那么要在FreeBSD下使用SR-IOV需要有哪些注意点?问题在于硬件和驱动。
Intel 10G网卡,比如X540-T2,是支持SR-IOV的。我原先对Intel的网卡印象非常好,非Intel网卡不用。但是这次没有调查清楚就掉坑了。入了X540-T2,在FreeBSD上被绊了一跤。驱动有BUG,可以打开SR-IOV但是无法使用。到Intel论坛上反应,倒是售后有人跟进,但是无实际进展。后来有一个高人指出来问题所在:
- FreeBSD的用户少,厂家没有动力去完善驱动。
- Intel的FreeBSD驱动,是从Linux上移植过来的。所以一些细节处理上,可能存在技术困难。这个很好理解,网卡驱动可能原生给Linux写的,然后再将代码适配到FreeBSD上。而Linux和FreeBSD虽然都是类Unix系统,但是底层完全不同,所以对于SR-IOV等功能的支持,Linux和FreeBSD可能相差甚远,基于原因1,所以这个功能不能用也不奇怪。另外,Intel的千兆网卡i350,硬件上也是支持SR-IOV的,Linux下面也能打开,但是FreeBSD上的驱动根本没有这个功能。
那么,我们需要购买支持FreeBSD的硬件!那就是厂家Chelsio!
这个厂家我从来都没听说过…孤陋寡闻一把。关键一点,这个厂家的网卡驱动,都已经集成在FreeBSD源码里面!无需另行下载安装!原生就是为FreeBSD写的驱动。它还是iXsystems这个公司的合作厂家!
iXsystems就是使用FreeBSD为做商用NAS的厂家。
我们这次选购一个chelsio的一个中端网卡,T520-CR,也就是长得下面这个样子:
三下五除二,给我的SuperMicro X9DRL-iF主板插上,顺利识别!这里有坑…
什么坑呢?我之前有一篇文章写了PCIe Bifurcation的介绍,如下:
主板的PCIe槽,看起来差不多都一样,其实有区别的。分两种,一种是原生CPU直连的PCIe,另一个种是通过PCH拆分的。一般的PCIe设备,插在上面这两种PCIe槽上都可以工作,只不过有可能有性能上的差别。但是要支持SR-IOV,PCIe设备只能插在CPU直接相连的PCIe插槽!!!
我最开始插到了PCH分出来的PCIe插槽上,虽然系统上可以设置直通和SR-IOV,但是不能使用!另外也会影响PCH上的其他设备,比如SATA控制器,导致硬盘报错…一度让我以为又翻船了… 此处省略了1万字的诉苦文,请看了我这段文章避开这个坑的同学一定要点赞赞赏啊…
网卡插到CPU直连的PCIe槽之后,T520-CR网卡需要手工指定加载驱动。这一点和Intel网卡直接自动加载驱动有点不同。直接命令行输入:
kldload if_cxgbe
或者在/boot/loader.conf中加入如下语句,开机时自动加载:
if_cxgbe_load="YES"
通过pciconf命令看一下设备情况:
root@vmhost168:~ # pciconf -lv | grep 520 -B 2 -A 2
t5iov0@pci0:4:0:0: class=0x020000 card=0x00001425 chip=0x50011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller'
class = network
subclass = ethernet
t5iov1@pci0:4:0:1: class=0x020000 card=0x00001425 chip=0x50011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller'
class = network
subclass = ethernet
t5iov2@pci0:4:0:2: class=0x020000 card=0x00001425 chip=0x50011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller'
class = network
subclass = ethernet
t5iov3@pci0:4:0:3: class=0x020000 card=0x00001425 chip=0x50011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller'
class = network
subclass = ethernet
t5nex0@pci0:4:0:4: class=0x020000 card=0x00001425 chip=0x54011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller'
class = network
subclass = ethernet
none6@pci0:4:0:5: class=0x010000 card=0x00001425 chip=0x55011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Storage Controller'
class = mass storage
subclass = SCSI
none7@pci0:4:0:6: class=0x0c0400 card=0x00001425 chip=0x56011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Storage Controller'
class = serial bus
subclass = Fibre Channel
这个网卡是一个Unified Wire adapter,缺省有t5iov0~3四个SR-IOV VF设备。(驱动缺省免配置就给了4个VF,赞!),然后有一个t5nex0,可以通过这个设备控制整个网卡。另外还有iSCSI和Fibre通道两个设备,这两个目前先不用,不管。
我们先不管缺省生成的VF,我们通过FreeBSD的配置文件生成更多VF出来。
生成/etc/cxl0.conf文件:
PF {
device:"cxl0";
num_vfs:8;
}
DEFAULT {
passthrough:true;
}
这个文件的语法比较简单,首先定义了PF设备是cxl0,然后需要创建8个VF设备。缺省的配置中,所有VF设备都用来直通(VF设备也是可以给主机使用的)。
通过下面的命令设置SR-IOV
root@vmhost168:~ # iovctl -C -f /etc/cxl0.conf
顺利的话,VF设备已经生成。我们再来看一下PCIe设备的情况。
root@vmhost168:~ # pciconf -lv | grep ppt -A 4
ppt2@pci0:4:0:8: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
ppt3@pci0:4:0:12: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
ppt4@pci0:4:0:16: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
ppt5@pci0:4:0:20: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
ppt6@pci0:4:0:24: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
ppt7@pci0:4:0:28: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
ppt8@pci0:4:0:32: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
ppt9@pci0:4:0:36: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
ppt2-ppt9一共8个VF已经生成了!
接下来就是分配VF给虚拟机了。
安装了一台FreeBSD虚拟机,配置如下:
loader="uefi"
graphics="yes"
xhci_mouse="yes"
cpu=2
memory=8G
disk0_type="ahci-hd"
disk0_name="disk0.img"
passthru0="4/0/8"
上面配置中,最后一句passthru0就是将pci0:4:0:8这个VF分配给虚拟机。
启动虚拟机!在虚拟机里面看一下设备信息:
root@sriov:~ # pciconf -lv
hostb0@pci0:0:0:0: class=0x060000 card=0x00000000 chip=0x12751275 rev=0x00 hdr=0x00
vendor = 'Network Appliance Corporation'
class = bridge
subclass = HOST-PCI
ahci0@pci0:0:3:0: class=0x010601 card=0x00000000 chip=0x28218086 rev=0x00 hdr=0x00
vendor = 'Intel Corporation'
device = '82801HR/HO/HH (ICH8R/DO/DH) 6 port SATA Controller [AHCI mode]'
class = mass storage
subclass = SATA
ahci1@pci0:0:4:0: class=0x010601 card=0x00000000 chip=0x28218086 rev=0x00 hdr=0x00
vendor = 'Intel Corporation'
device = '82801HR/HO/HH (ICH8R/DO/DH) 6 port SATA Controller [AHCI mode]'
class = mass storage
subclass = SATA
t5vf0@pci0:0:5:0: class=0x020000 card=0x00001425 chip=0x58011425 rev=0x00 hdr=0x00
vendor = 'Chelsio Communications Inc'
device = 'T520-CR Unified Wire Ethernet Controller [VF]'
class = network
subclass = ethernet
vgapci0@pci0:0:6:0: class=0x030000 card=0x00000000 chip=0x40fbfb5d rev=0x00 hdr=0x00
class = display
subclass = VGA
xhci0@pci0:0:7:0: class=0x0c0330 card=0x00000000 chip=0x1e318086 rev=0x00 hdr=0x00
vendor = 'Intel Corporation'
device = '7 Series/C210 Series Chipset Family USB xHCI Host Controller'
class = serial bus
subclass = USB
isab0@pci0:0:31:0: class=0x060100 card=0x00000000 chip=0x70008086 rev=0x00 hdr=0x00
vendor = 'Intel Corporation'
device = '82371SB PIIX3 ISA [Natoma/Triton II]'
class = bridge
subclass = PCI-ISA
t5vf0这个VF已经顺利识别和配置!
我们来看一下性能如何:
root@nas253:~ # iperf3 -c 192.168.11.22
Connecting to host 192.168.11.22, port 5201
[ 5] local 192.168.11.253 port 50086 connected to 192.168.11.22 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 1023 MBytes 8.58 Gbits/sec 0 769 KBytes
[ 5] 1.00-2.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.54 MBytes
[ 5] 2.00-3.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.78 MBytes
[ 5] 3.00-4.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.78 MBytes
[ 5] 4.00-5.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.78 MBytes
[ 5] 5.00-6.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.78 MBytes
[ 5] 6.00-7.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.78 MBytes
[ 5] 7.00-8.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.78 MBytes
[ 5] 8.00-9.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.78 MBytes
[ 5] 9.00-10.00 sec 1.15 GBytes 9.90 Gbits/sec 0 1.78 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 11.4 GBytes 9.77 Gbits/sec 0 sender
[ 5] 0.00-10.00 sec 11.4 GBytes 9.76 Gbits/sec receiver
iperf Done.
上面是两个虚拟机之间的iperf测试情况,ESXi上的虚拟机使用Intel X540-T2的VF,FreeBSD上的虚拟机使用Chelsio T520-CR的VF,中间通过QNAP的万兆交换机互联。
9.9Gbits/sec,基本就是10G网卡的极限了。
总结一下,要想在FreeBSD使用SR-IOV,需要注意以下几点:
- 主板支持SR-IOV
- 硬件上选用Chelsio的网卡
- 网卡插到CPU直通的PCIe插槽
最后一个彩蛋!同一个网卡,两个虚拟机之间的速度能超过10G,达到惊人了30G。
如果你喜欢今后能多看到类似的文章,请看完之后点赞收藏分享,这样子我就可以有动力多写一些啦~~~