I/O 虛擬化的三種形式
本文首發於我的公眾號 cloud_dev ,專注於乾貨分享,號內有大量書籍和視訊資源,後臺回覆 「1024」 即可領取,歡迎大家關注,二維碼文末可以掃。
上文「I/O 虛擬化」簡單介紹了 I/O 虛擬化的做法,本文重點關注一下三種 I/O 虛擬化的分類——全虛擬化、半虛擬化和 I/O 直通(透傳)。
I/O 全虛擬化
這種方式比較好理解,簡單來說,就是通過純軟體的形式來模擬虛擬機器的 I/O 請求。以 qemu-kvm 來舉例,核心中的 kvm 模組負責截獲 I/O 請求,然後通過事件通知告知給使用者空間的裝置模型 qemu,qemu 負責完成本次 I/O 請求的模擬。更具體的內容可以翻閱前文。

image
優點:
不需要對作業系統做修改,也不需要改驅動程式,因此這種方式對於多種虛擬化技術的「可移植性」和「相容性」比較好。
缺點:
純軟體形式模擬,自然效能不高,另外,虛擬機發出的 I/O 請求需要虛擬機器和 VMM 之間的多次互動,產生大量的上下文切換,造成巨大的開銷。
I/O 半虛擬化
針對 I/O 全虛擬化純軟體模擬效能不高這一點,I/O 半虛擬化前進了一步。它提供了一種機制,使得 Guest 端與 Host 端可以建立連線,直接通訊,摒棄了截獲模擬這種方式,從而獲得較高的效能。
值得注意的有兩點:1)採用 I/O 環機制,使得 Guest 端和 Host 端可以共享記憶體,減少了虛擬機器與 VMM 之間的互動;2)採用事件和回撥的機制來實現 Guest 與 Host VMM 之間的通訊。這樣,在進行中斷處理時,就可以直接採用事件和回撥機制,無需進行上下文切換,減少了開銷。
要實現這種方式, Guest 端和 Host 端需要採用類似於 C/S 的通訊方式建立連線,這也就意味著要修改 Guest 和 Host 端作業系統核心相應的程式碼,使之滿足這樣的要求。為了描述方便,我們統稱 Guest 端為前端,Host 端為後端。

image
前後端通常採用的實現方式是驅動的方式,即前後端分別構建通訊的驅動模組,前端實現在核心的驅動程式中,後端實現在 qemu 中,然後前後端之間採用共享記憶體的方式傳遞資料。關於這方面一個比較好的開源實現是 virtio,後面會有專門的文章來講述之。
優點:
效能較 I/O 全虛擬化有了較大的提升
缺點:
要修改作業系統核心以及驅動程式,因此會存在移植性和適用性方面的問題,導致其使用受限。
I/O 直通或透傳技術
上面兩種虛擬化方式,還是從軟體層面上來實現,效能自然不會太高。最好的提高效能的方式還是從硬體上來解決。如果讓虛擬機器獨佔一個物理裝置,像宿主機一樣使用物理裝置,那無疑效能是最好的。
I/O 直通技術就是提出來完成這樣一件事的。它通過硬體的輔助可以讓虛擬機器直接訪問物理裝置,而不需要通過 VMM 或被 VMM 所截獲。
由於多個虛擬機器直接訪問物理裝置,會涉及到記憶體的訪問,而記憶體又是共享的,那怎麼來隔離各個虛擬機器對記憶體的訪問呢,這裡就要用到一門技術——IOMMU,簡單說,IOMMU 就是用來隔離虛擬機器對記憶體資源訪問的。
I/O 直通技術需要硬體支援才能完成,這方面首選是 Intel 的 VT-d 技術,它通過對晶片級的改造來達到這樣的要求,這種方式固然對效能有著質的提升,不需要修改作業系統,移植性也好。
但該方式也是有一定限制的,這種方式僅限於物理資源豐富的機器,因為這種方式僅僅能滿足一個裝置分配給一個虛擬機器,一旦一個裝置被虛擬機器佔用了,其他虛擬機器時無法使用該裝置的。

image
為了解決這個問題,使一個物理裝置能被更多的虛擬機器所共享。學術界和工業界都對此作了大量的改進,PCI-SIG 釋出了 SR-IOV (Single Root I/O Virtualizmion) 規範,其中詳細闡述了硬體供應商在多個虛擬機器中如何共享單個 I/O 裝置硬體。
SR-IOV標準定義了裝置原生共享所需的「軟硬體支援」。硬體支援包括晶片組對 SR-IOV 裝置的識別,為保證對裝置的安全、隔離訪問還需要北橋晶片的 VT-d 支援,為保證虛擬機器有獨立的記憶體空間,CPU 要支援 IOMMU。軟體方面,VMM 將驅動管理許可權交給 Guest,Guest 作業系統必須支援 SR-IOV 功能。
SR-IOV 單獨引入了兩種軟體實體功能:
-
PF(physical function):包含輕量級的 PCIe 功能,負責管理 SR-IOV 裝置的特殊驅動,其主要功能是為 Guest 提供裝置訪問功能和全域性貢獻資源配置的功能。
-
VF(virtual function):包含輕量級的 PCIe 功能。其功能包含三個方面:向虛擬機器作業系統提供的介面;資料的傳送、接收功能;與 PF 進行通訊,完成全域性相關操作。
每個 SR-IOV 裝置都可有一個物理功能 PF,並且每個 PF 最多可有 64,000 個與其關聯的虛擬功能 VF。
一般,Guest 通過物理功能 PF 驅動發現裝置的 SR-IOV 功能後將包括髮送、接收佇列在內的物理資源依據 VF 數目劃分成多個子集,然後 PF 驅動將這些資源子集抽象成 VF 裝置,這樣,VF 裝置就可以通過某種通訊機制分配給虛擬機器了。

image
儘管 I/O 直通技術消除了虛擬機器 I/O 中 VMM 干預引起的額外開銷,但在 I/O 操作中 I/O 裝置會產生大量的中斷,出於安全等因素考慮,虛擬機器無法直接處理中斷,因此中斷請求需要由 VMM 安全、隔離地路由至合適的虛擬機器。所以,其實實際使用中,都是軟硬體虛擬化方式結合使用的。
我的公眾號 cloud_dev ,號內有大量書籍和視訊資源,後臺回覆 「1024」 即可領取,分享的內容包括但不限於雲端計算虛擬化、容器、OpenStack、K8S、霧計算、網路、工具、SDN、OVS、DPDK、Linux、Go、Python、C/C++程式設計技術等內容,歡迎大家關注。

image