基於KVM的SRIOV直通配置及效能測試

基於KVM的SRIOV直通配置及效能測試

SRIOV介紹、VF直通配置,以及包轉發率效能測試

小慢哥的原創文章,歡迎轉載

目錄

▪ 1。 SRIOV介紹

▪ 2。 環境說明

▪ 3。 開啟SRIOV

▪ 4。 生成VF

▪ 5。 VF直通

▪ 6。 開啟irqbalance

▪ 7。 VM遷移

▪ 8。 頻寬限速

▪ 9。 安全

▪ 10。 其他使用限制

▪ 11。 效能測試

▪ 12。 windows虛擬機器使用VF

▪ 13。 運維命令

▪ 14。 宿主遮蔽VF驅動

▪ 附。 包轉發率測試方法

▪ 附。 參考文件

1。 SRIOV介紹

基於KVM的SRIOV直通配置及效能測試

傳統方式的瓶頸

:qemu的網絡卡,傳統方式是使用tap網絡卡,橋接到宿主的bridge上,但效能很差,尤其是包轉發率很低,難以滿足對效能要求比較高的場景。效能差的主要原因是路徑太長,經過的核心裝置太多,根本原因在於linux/unix核心本身就不是為高效能而設計的,linux/unix更適合做控制平面,而不是轉發平面。

解決思路

:減少中間路徑,最簡單有效的方法就是bypass核心。SRIOV的作用就是bypass宿主核心。

PF和VF

:每個物理網絡卡(比如p1p1)就是一個PF,在開啟SRIOV後,每個PF可以生成固定數量的VF,每個VF都可以在宿主上作為一張網絡卡直接使用,或者直通到QEMU虛擬機器裡作為虛擬機器裡的網絡卡使用,這就實現了bypass宿主核心。

先給出效能測試的結論,SRIOV VF直通相比傳統tap+bridge方案,效能提升:

▷ 發包轉發率提高: 677%

▷ 收包轉發率提高: 171%

2。 環境說明

機型:Dell PowerEdge R620

網絡卡:Intel X520(82599ES)

宿主OS:CentOS 7

VM OS:CentOS 7

3。 開啟SRIOV

1️⃣

在BIOS裡開啟SRIOV,如圖所示

基於KVM的SRIOV直通配置及效能測試

注:即使BIOS裡開啟全域性SRIOV,網絡卡也依然可以當作普通網絡卡使用

2️⃣

需要在BIOS裡開啟VT-d

3️⃣

grub配置iommu

iommu=pt intel_iommu=on

4。 生成VF

# 啟動網絡卡ip link set p1p1 up# 檢視pf的pci編號lshw -c network -businfo# 檢視網絡卡支援的vf數量cat /sys/bus/pci/devices/0000:41:00。0/sriov_totalvfs# 生成vf,建議加入開機啟動echo 63 > /sys/bus/pci/devices/0000:41:00。0/sriov_numvfs

注意:若沒有遮蔽宿主的VF驅動,則在生成vf後還必須等待一會時間才能在宿主上看到所有命名完成的網絡卡(否則會看到一堆ethX網絡卡),vf數量越多需要等待時間越長,63個vf,差不多需要10秒

5。 VF直通

如果qemu是透過libvirt管理的,有3種配置方法:

方法1(interface):在devices段落里加入

上面中address的地址,可以根據“lshw -c network -businfo”來配置,比如

pci@0000:41:10。0 p1p1_0

方法2(hostdev):在devices段落里加入

上面中address的地址,也是根據“lshw -c network -businfo”來配置

方法3(net-pool)

為每個PF網絡卡定義一個net-pool,即分別編輯一個xml檔案。這裡僅展示一個PF,編輯sriov-int。xml

sriov-int

加入到libvirt net-pool、啟用、並設定開機啟動

virsh net-define sriov-int。xmlvirsh net-start sriov-intvirsh net-autostart sriov-int

雖然配置了net-autostart,但並不管用,因為物理機啟動時候,經常會在啟動生成vf(假設在rc。local裡生成vf)之前就啟動libvirt,而這個net-pool(sriov-int)本應該在vf生成後才能啟動,因此建議在rc。local裡增加如下內容來確保啟動

ip link set p1p2 upecho 63 > /sys/bus/pci/devices/0000:41:00。0/sriov_numvfsvirsh net-start sriov-int

然後,在vm的xml裡增加

3種方法如何選擇

▷ 方法1:功能多,可以配置mac和vlan

▷ 方法2:mac和vlan需要自己在宿主上敲ip命令設定

▷ 方法3:有2個問題

▪ 存在一個bug,當本宿主所有vm使用某個PF的VF總數超過VF上限後,不會報錯,也能啟動,但是可能會有異常,並且vm如果被destroy關機,那麼對應的VF就會出問題,比如使用ip link set p1p1 vf 0 mac 00:00:00:00:00:00來做重置時候,會提示“RTNETLINK answers: Cannot allocate memory”,而且難以修復,即使修復,也不知道有沒有看不見的異常存在。

▪ 沒有辦法知道某個vm使用的是哪個vf,因此如果要對vf設定限速或者開關spoofchk時候,只能先在宿主上透過“ip link show dev p1p1 | grep MAC地址”方式來獲得vf號,然後才能設定限速等操作

綜上所述:使用方法3最便捷,但是存在bug,因此需要做好邏輯來防止vm使用vf總數超過上限的情況。

6。 開啟irqbalance

x520是2佇列,x710是4佇列,需要在vm裡啟動中斷平衡服務(irqbalance),否則只會有一個cpu來處理資料包。

另外,這與宿主上vf的query_rss無關。

7。 VM遷移

直通網絡卡屬於PCI裝置,而libvirt和qemu卻不支援帶有非USB的PCI裝置的vm做遷移,包括冷遷移和熱遷移。因此熱遷移無法實現。

冷遷移,有2種方案:

▷ detach掉vf網絡卡,然後使用libvirt做遷移,遷移過去後,再在新宿主上attach vf網絡卡

▷ undefine vm,然後在新宿主上重新渲染並define vm

注意:不能在vm關機時候用libvirt的遷移功能,有時候會導致虛擬機器消失掉,包括原宿主和新宿主

8。 頻寬限速

只能限制出站頻寬,無法限制入站頻寬

ip link set p1p1 vf 0 max_tx_rate 100

表示出站頻寬限速100Mbps,不同網絡卡有差別:

▷ x520網絡卡最小限速11Mbps,最大限速10000Mbps,設為0表示不限速。

若小於11或大於10000則會報錯

▷ x710網絡卡最小限速50Mbps,最大限速10000Mbps,設為0表示不限速。

若小於50則自動設為50,若大於10000則會報錯

注意:vm關機後vf的頻寬限速不會復位

9。 安全

僅支援源mac過濾和網絡卡mac防篡改,不支援其他安全防護(防arp欺騙就無法實現)

源mac過濾

ip link set p1p1 vf 0 spoofchk on

表示vm裡發出的包,如果源mac不是指定mac,那麼資料包不允許透過。注意:vm關機後vf的spoofchk不會復位

網絡卡mac防篡改

▷ 在宿主上修改mac,vm裡的mac不會跟著改;在vm裡修改mac,在宿主上可以看到變化

▷ 如果在vm關機狀態下改了mac地址,那麼當vm開機後會改為vm的mac,當vm又關機後,又回改為原先改的mac

▷ 只有在宿主上看到的當前vf的mac為全0,才能在vm裡修改mac地址,即使vf的spoofchk為off。但有一種例外,若使用上面方法2來配置xml,雖然宿主上看到的vf的mac不為0,但vm裡可以修改

▷ 當在宿主上設定了mac後,虛擬機器裡的mac就無法篡改了

▪ 方法1(interface)來配置xml,估計vm啟動時候就自動幫忙在宿主上設定了mac,所以就直接實現了防篡改功能

▪ 方法2(hostdev)來配置xml,需要在宿主上手動再設定一次mac地址才能實現防篡改

在宿主上手動修改mac方法(vm關機和開機情況下都可以改):

ip link set p1p1 vf 0 mac aa:bb:cc:dd:ee:ff

建議:

▷ 在vm啟動前對vf做一次重置

▷ 在vm undefine後對vf做一次重置

10。 其他使用限制

▷ 直通到vm裡的vf網卡里無法橋接到vm裡的linux bridge,這也導致ebtables無法使用,iptables可以使用

▷ 直通到vm裡的vf網絡卡可以加入ovs橋接

▷ 一個vm最多隻能支援32個vf,超過數量會報錯

11。 效能測試

測試方法:

▷ 多臺vm同時發包,一臺vm收包,分別觀察發包效能和收包效能

▷ 發包vm在同一臺宿主上,收包vm在另一臺宿主上

▷ 測試工具:modprobe pktgen

▷ 測試包大小: udp包,size為64 bytes

配置:

▷ vm配置均為4核8G

▷ 物理網絡卡均為x520(vf佇列預設為2)

▷ 宿主和vm均開啟irqbalance、均關閉numad

▷ 不配置cpu繫結、不配置numa繫結

▷ 開啟大頁

測試結果:

基於KVM的SRIOV直通配置及效能測試

測試結論:

使用SR-IOV+VF直通方式可以明顯提升包轉發率,1對1的測試結果看到

kernel態發包可以達到3.5Mpps,收包可以達到1.9Mpps

▷ 發包比vxlan提高: 1196%,比vlan提高: 677%。此結果參考1對1(1個發包vm,1個收包vm)

▷ 收包比vxlan提高: 363%,比vlan提高: 171%。此結果參考3對1(3個發包vm,1個收包vm)

說明:

▷ kernel態單核資料包(64B)處理能力為2Mpps

▷ 2Mpps是因為kernel態瓶頸是2Mpps,如果透過dpdk走使用者態,則可以大於2M,原因:收包端要將資料包中斷平衡到不同的cpu上,方法:可以透過多佇列方式,把每個佇列分配到單獨cpu上(irqbalance會自動均衡),然後source ip不一樣,就會對應到不同佇列,也就是不同的中斷上。即1個VF,2個佇列,VM有至少2核,那麼當符合負載均衡條件(mac、ip不同),則理論上最大可以達到4Mpps

更多測試結果:

以下測試使用的packet大小為64B

▷ kernel態,3層轉發效能:發包器使用不同的source ip

▪ BCM57800:2Mpps

▪ Intel X520:10Mpps

▪ Intel X710:12Mpps

▷ kernel態,2層轉發效能:發包器使用不同的source mac

▪ BCM57800:2Mpps

▪ Intel X520:7。3Mpps

▪ Intel X710:7。8Mpps

▷ kernel態下vxlan封裝能力

▪ vxlan內層使用不同的source ip發包

▪ 收包在:1。1-1。2Mpps

▷ dpdk使用者態,2層轉發效能:發包器使用不同的source ip

▪ BCM57800:不支援

▪ Intel X520:14。8Mpps

▪ Intel X710:14。8Mpps

▷ SR-IOV模式

▪ X520總量11。2Mpps,每vm為11。2Mpps/vm總數(即VF數)

總結:

▷ kernel態下的中斷平衡的依據因素:2層依據source mac,3層依據source ip

▷ kernel態下使用傳統中斷模式的單核轉發能力極限2Mpps

注意:

▷ kernel態下,利用多佇列RSS中斷平衡提升吞吐率,會導致cpu非常高

▷ 使用者態下即使source mac或source ip固定,吞吐率基本接近限速14。8Mpps

▷ vxlan不能利用多核來提升吞吐,主要原因為外層source ip不夠多

12。 windows虛擬機器使用VF

到網絡卡官網下載對應驅動並安裝,經測試,win2012預設就有82599(x520)驅動,但版本舊

13。 運維命令

# 檢視網絡卡支援的vf數量cat /sys/bus/pci/devices/0000:41:00。0/sriov_totalvfs# 宿主遮蔽VF驅動後檢視vf和pf的對應https://github。com/intel/SDN-NFV-Hands-on-Samples/blob/master/SR-IOV_Network_Virtual_Functions_in_KVM/listvfs_by_pf。sh載下來後執行。/listvfs_by_pf。sh即可# 宿主遮蔽VF後檢視哪些VF正在被使用yum install dpdk-toolsdpdk-devbind ——status# 檢視網絡卡對應哪個socketlstopo-no-graphics# lspci檢視網絡卡資訊lspci -Dvmm|grep -B 1 -A 4 Ethernet# 宿主上檢視具體VF流量(僅支援x520,x710查不到)ethtool -S p1p1 | grep VF

14。 宿主遮蔽VF驅動

echo “blacklist ixgbevf” >> /etc/modprobe。d/blacklist。conf

表示當物理機啟動時候,預設不載入ixgbevf驅動,但是如果手動modprobe ixgbevf,則也會載入驅動。

如果當前已經載入了ixgbevf,想解除安裝,則需要如下步驟

echo 0 > /sys/bus/pci/devices/0000:41:00。0/sriov_numvfsrmmod ixgbevfecho 63 > /sys/bus/pci/devices/0000:41:00。0/sriov_numvfs

附。 包轉發率測試方法

modprobe pktgen

:發包透過pktgen來發,收包透過sar -n DEV來看,發的是udp包

#!/bin/bashNIC=“eth1”DST_IP=“192。168。1。2”DST_MAC=“52:54:00:43:99:65”modprobe pktgenpg() { echo inject > $PGDEV cat $PGDEV}pgset() { local result echo $1 > $PGDEV result=`cat $PGDEV | fgrep “Result: OK:”` if [ “$result” = “” ]; then cat $PGDEV | fgrep Result: fi}# Config Start Here ——————————————————————————————-# thread config# Each CPU has own thread。 Two CPU exammple。 We add ens7, eth2 respectivly。PGDEV=/proc/net/pktgen/kpktgend_0echo “Removing all devices”pgset “rem_device_all”echo “Adding ${NIC}”pgset “add_device ${NIC}”# device config# delay 0 means maximum speed。CLONE_SKB=“clone_skb 1000000”# NIC adds 4 bytes CRCPKT_SIZE=“pkt_size 64”# COUNT 0 means foreverCOUNT=“count 0”DELAY=“delay 0”PGDEV=/proc/net/pktgen/${NIC}echo “Configuring $PGDEV”pgset “$COUNT”pgset “$CLONE_SKB”pgset “$PKT_SIZE”pgset “$DELAY”pgset “dst ${DST_IP}”pgset “dst_mac ${DST_MAC}”# Time to runPGDEV=/proc/net/pktgen/pgctrlecho “Running。。。 ctrl^C to stop”pgset “start”echo “Done”# Result can be vieved in /proc/net/pktgen/eth[3,4]

▷ 將指令碼開頭的eth1改為發包對應的網絡卡

▷ 將指令碼開頭的192。168。1。2改為目標ip

▷ 將指令碼開頭的52:54:00:43:99:65改為目標mac

pktgen-dpdk

# 固定ip固定macset 0 dst ip 192。168。10。240set 0 src ip 192。168。10。245/24set 0 dst mac c8:1f:66:d7:58:baset 0 src mac a0:36:9f:ec:4a:28# 可變source ip可變source macstop 0range 0 src ip 192。168。0。1 192。168。0。1 192。168。200。200 0。0。0。1range 0 dst ip 10。1。1。241 10。1。1。241 10。1。1。241 0。0。0。0range 0 dst mac c8:1f:66:d7:58:ba c8:1f:66:d7:58:ba c8:1f:66:d7:58:ba 00:00:00:00:00:00range 0 src mac a0:36:9f:ec:4a:28 a0:36:9f:ec:4a:28 a0:36:9f:ec:ff:ff 00:00:00:00:01:01range 0 src port 100 100 65530 1range 0 dst port 100 100 65530 1range 0 size 64 64 64 0enable 0 rangeenable 0 latencystart 0# 按50%的速率發包set 0 rate 50

附。 參考文件

# openstack關於sriov的限制https://docs。openstack。org/mitaka/networking-guide/config-sriov。html# 遷移https://wenku。baidu。com/view/d949db67998fcc22bcd10dfd。htmlhttps://www。chenyudong。com/archives/live-migrate-with-pci-pass-through-fail-with-libvirt-and-qemu。html# sriov配置https://access。redhat。com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_host_configuration_and_guest_installation_guide/sect-virtualization_host_configuration_and_guest_installation_guide-sr_iov-how_sr_iov_libvirt_works# 線速http://netoptimizer。blogspot。tw/2014/05/the-calculations-10gbits-wirespeed。html