數(shù)據(jù)包的拷貝是虛擬化網(wǎng)絡(luò)中最大的性能瓶頸,這些年來,人們也一直在致力于減少內(nèi)存拷貝甚至消除內(nèi)存拷貝拦宣。根據(jù)數(shù)據(jù)包流向,零拷貝可以分為 Host to VM 的零拷貝和 VM to VM 的零拷貝,前者主要適用于一般的情況鸵隧,后者更適用于NFV绸罗。本文簡單枚舉下現(xiàn)有的零拷貝的虛擬化網(wǎng)絡(luò)實現(xiàn)。
1.Host to VM零拷貝
除去之前的文章中講過的設(shè)備透傳之外豆瘫,數(shù)據(jù)包到達物理網(wǎng)卡在轉(zhuǎn)發(fā)之前都必須被存儲在主機的數(shù)據(jù)包緩沖區(qū)中珊蟀,這樣要想實現(xiàn)零拷貝,必須允許虛擬機能夠直接訪問該處的數(shù)據(jù)包⊥馇現(xiàn)有實現(xiàn)有兩種方式育灸,一種是采用更決絕的共享內(nèi)存技術(shù),另一種是在EPT頁表層面做一些動態(tài)修改昵宇。
基于共享內(nèi)存實現(xiàn)零拷貝
早在09年就有一位博士在自己的畢業(yè)設(shè)計中提出了一種零拷貝的虛擬化網(wǎng)絡(luò)IO接口實現(xiàn)磅崭,并以Nahanni命名了這種設(shè)計的設(shè)備和驅(qū)動名[1,2],這便是IVSHMEM的前身瓦哎。但是不幸的是砸喻,盡管這位博士在自己論文中以極具攻擊性的語氣詆毀了社區(qū)選擇virtio方案的愚蠢行為,但是由于這種共享內(nèi)存的設(shè)計太過大膽蒋譬,存在嚴重的安全隱患恩够,因而始終不被內(nèi)核開發(fā)者接納。
幾年以后羡铲,這項技術(shù)反而在一個新興的方向被提出蜂桶,而被更多人知曉。也許沒有很多人知道IVSHMEM也切,但一定知道14年NSDI計算機網(wǎng)絡(luò)頂級會議上提出的NetVM扑媚,他使用的是相同的設(shè)計思想,將之應(yīng)用于NFV領(lǐng)域雷恃,并實現(xiàn)了編程所需的基本框架[3]疆股。NetVM代表了虛擬化網(wǎng)絡(luò)IO中零拷貝共享內(nèi)存是最好實現(xiàn),那么這里就用NetVM為例介紹一下這種技術(shù)如何發(fā)揮作用倒槐。
他實現(xiàn)零拷貝的思路就是:讓host的數(shù)據(jù)包buffer共享給VM旬痹,使得VM有能力直接訪問主機上屬于自己的數(shù)據(jù)包。另外讨越,還需要共享一對隊列两残,用于VM與host傳輸數(shù)據(jù)包過程中的交互,互相指明數(shù)據(jù)包存在哪了把跨。
這項方式有兩點缺點:由于需要VM實現(xiàn)對共享內(nèi)存內(nèi)部數(shù)據(jù)包的直接讀热斯(無須拷貝到自己的buffer),就需要在VM中改寫專有驅(qū)動着逐,來完成對共享內(nèi)存這塊buffer的內(nèi)存管理崔赌;對于多個VM共享一塊內(nèi)存作為數(shù)據(jù)包緩沖區(qū)意蛀,意味著上面的數(shù)據(jù)包可以隨意訪問,存在安全性隱患健芭。也正是這兩點原因县钥,這項方案難以大規(guī)模使用。
但是它在NFV環(huán)境下慈迈,多VM共享一塊內(nèi)存的設(shè)計卻是提升性能的關(guān)鍵若贮。因為NFV旨在利用虛擬化的資源(如:VM或者容器)來實現(xiàn)物理設(shè)備實現(xiàn)的網(wǎng)絡(luò)功能,從而構(gòu)成服務(wù)鏈吩翻,也就是說一條服務(wù)鏈上可能有很多個運行不同網(wǎng)絡(luò)功能的虛擬機,數(shù)據(jù)包(flow)需要穿過這么多虛擬機锥咸,內(nèi)存拷貝會讓性能急劇下降狭瞎。因此,在NetVM方案下搏予,一個數(shù)據(jù)包可以同時被一條服務(wù)鏈上所有的VM訪問熊锭,結(jié)合一些NFV并行化的操作,可以大大提高NFV的性能雪侥。
下面簡要說明一下這種直接host與VM共享內(nèi)存是如何實現(xiàn)的吧碗殷。
答案還是設(shè)備模擬,使用設(shè)備內(nèi)存速缨。QEMU是VM主進程锌妻,也是負責給VM提供所有的設(shè)備模擬的。在啟動VM的時候旬牲,QEMU給VM虛擬出來一個PCI設(shè)備仿粹,并將host的buffer作為設(shè)備內(nèi)存注冊進設(shè)備的數(shù)據(jù)結(jié)構(gòu)。這樣一旦VM需要訪問設(shè)備的時候原茅,就會被重定向到host的buffer吭历。
page-flipping實現(xiàn)零拷貝
這項技術(shù)在十年前,就有人提出并在Xen虛擬化機制上做了實現(xiàn)擂橘。最近晌区,也有人把它實現(xiàn)在了QEMU/KVM虛擬化上,并且基于的是vhost-user做改動[4]通贞。
這種方法的設(shè)計思想是:VM內(nèi)存訪問是經(jīng)過EPT頁表朗若,將GPA(Guest Physical Address)翻譯成HPA(Host Physical Address),既然這樣就可以不用共享內(nèi)存昌罩,直接改數(shù)據(jù)包所在頁的EPT頁表表項捡偏,使得VM訪存時被重定向到數(shù)據(jù)包所在的物理頁。
這種方式就是“簡單粗暴”峡迷,需要修改網(wǎng)卡驅(qū)動對內(nèi)存的管理银伟,以及KVM內(nèi)核代碼你虹,允許EPT表項映射關(guān)系被動態(tài)修改。這也正是其缺陷所在彤避,不論數(shù)據(jù)包大小傅物,每次數(shù)據(jù)包傳輸都需要改EPT表項,而這是一個很昂貴的操作琉预。實驗結(jié)果表明董饰,它拖累了小包的傳輸,只有在數(shù)據(jù)包大小超過1518字節(jié)(那也就是只有巨型幀了)圆米,這種方式才比數(shù)據(jù)包拷貝要快卒暂。
2.VM to VM零拷貝
其實上面所說的NetVM和IVSHMEM已經(jīng)實現(xiàn)的VM間零拷貝了,這里就說下vhost-user尚未開源的一些設(shè)計娄帖。
因為virtio已經(jīng)被社區(qū)接納并且進入大部分操作系統(tǒng)的內(nèi)核也祠,因此對基于virtio的各項feature的優(yōu)化,還是有很多人在做近速。我這里要說的就是virtio在VM間共享內(nèi)存的技術(shù)vhost-pci诈嘿。
它的想法非常直接,如果一個VM能夠直接從另一個VM中讀取數(shù)據(jù)包而不需要拷貝削葱,那么可以極大加快服務(wù)鏈上的效率奖亚。這在實現(xiàn)上非常類似NetVM和IVSHMEM,為需要進行VM to VM傳輸?shù)腣M虛擬一個熱插拔設(shè)備叫做vhost-pci析砸,設(shè)備內(nèi)存就是另一個VM的內(nèi)存昔字,在VM中再實現(xiàn)一套驅(qū)動,讓VM間通信變得類似于vhost-user的前后端操作首繁,就可以實現(xiàn)零拷貝李滴。在github上已經(jīng)有vhost-pci的實現(xiàn)了:https://github.com/wei-w-wang/vhost-pci,不知道為什么沒有推進社區(qū)蛮瞄。
關(guān)于虛擬機間通信所坯,Intel和開源社區(qū)也還有一個更靈活的想法,讓每個QEMU進程有“弱交換機”的功能挂捅,VM在往外發(fā)送數(shù)據(jù)包的時候由這個“弱交換機”判斷是VM間通信還是與外部通信芹助,從而確定走vhost-pci快速通道還是走OVS轉(zhuǎn)發(fā)。而這些QEMU“弱交換機”還會和OVS進行交互更新流表項等操作闲先。當初見到這個設(shè)計的時候真的佩服設(shè)計者的腦洞状土,但是現(xiàn)在還是停在原型驗證階段,可能里面還有什么巨坑吧伺糠。
但是這項快速通路帶來了另一個問題——安全問題蒙谓。考慮到允許一個VM直接訪問另一個VM內(nèi)存训桶,這是一項極其危險的操作累驮,如果能有一個“protected view”去做這項事情就好了酣倾。
為了實現(xiàn)這項安全地訪問外部資源(敏感資源)的技術(shù),Intel直接在硬件層面上下功夫了谤专,并為此申請了全球?qū)@晡_@項技術(shù)叫做EPTP switching。這項技術(shù)允許一個VM擁有多個EPT頁表置侍,通過寫寄存器映之,實現(xiàn)EPT頁表之間的切換。
科普一下蜡坊,它不僅可以用于安全地訪問外部資源上杠输,由于它的開銷極低,一些虛擬機內(nèi)存監(jiān)視器也使用了該方法秕衙。去年“熔斷”和“幽靈”兩大漏洞讓Linux社區(qū)為此重新設(shè)計了頁表蠢甲,提出的KPTI讓性能降低很多;因此有人認為在云上灾梦,虛擬機可以不用打這么大開銷的補丁峡钓,可以直接利用多項EPT頁表技術(shù)來實現(xiàn)對VM內(nèi)存的監(jiān)視[5]妓笙。
回到vhost-pci策略上來若河,我們?yōu)橐粋€VM建立兩個EPT頁表:一個是default頁表,另一個是包含別的VM內(nèi)存的EPT頁表寞宫∠舾#可以調(diào)用VMFUNC中的EPTP switching在這兩種頁表之間切換。
在這種機制下的數(shù)據(jù)包傳輸就變成上圖這樣:在進入發(fā)送函數(shù)時辈赋,目的VM的內(nèi)存是不可見的鲫忍;先調(diào)用VMFUNC切換到protected view,目的VM的內(nèi)存可見钥屈,進行數(shù)據(jù)包send悟民;發(fā)送完以后,再調(diào)用VMFUNC切換default EPT頁表篷就,目的VM的內(nèi)存又變得不可見了射亏。
這樣就實現(xiàn)了既安全又高效的VM間數(shù)據(jù)傳輸,可惜這套方案已經(jīng)被專利保護竭业,再沒有發(fā)揮余地了智润。
引用:
[1] Macdonell A C. Shared-memory optimizations for virtual machines[J]. 2011.
[2] MacDonell C. Nahanni, a shared memory interface for kvm[J]. Aug, 2010, 10: 19.
[3] Hwang J, Ramakrishnan K K, Wood T. NetVM: High Performance and Flexible Networking Using Virtualization on Commodity Platforms[C]//11th {USENIX} Symposium on Networked Systems Design and Implementation ({NSDI} 14). 2014: 445-458.
[4] Wang D, Hua B, Lu L, et al. Zcopy-vhost: Eliminating Packet Copying in Virtual Network I/O[C]//2017 IEEE 42nd Conference on Local Computer Networks (LCN). IEEE, 2017: 632-639.
[5] Hua Z, Du D, Xia Y, et al. {EPTI}: Efficient Defence against Meltdown Attack for Unpatched VMs[C]//2018 {USENIX} Annual Technical Conference ({USENIX}{ATC} 18). 2018: 255-266.
vhost-pci中圖 來源于 “Extending KVM Models Toward High-Performance NFV; Jun Nakajima, James Tsai, Mesut Ergin, Yang Zhang, and Wei Wang; Intel”