Linux 操作系統原理 — 網絡 I/O 虛擬化
目錄
文章目錄
目錄
IOMMU — CPU 硬件支撐的 I/O 虛擬化方案
需求背景
DMA Remapping Feature
IOMMU 硬件單元
PCI Passthrough
開啟 IOMMU
UIO Framework — 用戶態網絡協議棧方案
VFIO — VNF/CNF 的用戶態網絡協議棧方案
IOMMU Group
IOMMU — CPU 硬件支撐的 I/O 虛擬化方案
需求背景
多個虛擬機共享服務器中的物理網卡,該場景中需要一種機制既能保證 I/O 的效率,又要保證多個虛擬機對用物理網卡共享使用。I/O 虛擬化的出現就是為了解決這類問題。
DMA Remapping Feature
從 CPU 的角度看,為了解決虛擬機訪問物理網卡等 I/O 設備的性能問題,就是要避免 VMM 對 CPU 指令的捕獲/翻譯、上下文切換、內存拷貝等損耗,于是提出了 DMA Remapping Feature(DMA(直接存儲器存取)的重映射功能),即:虛擬機可以通過 DMA Remapping Feature 直接訪問到宿主機的物理網卡設備的內存空間,且進行安全訪問,故稱這段地址空間為:虛擬機對網卡訪問的 DMA 保護域。
DMA Remapping Feature 主要解決了兩個問題:
一方面為每個虛擬機創建了一個 DMA 保護域并實現了安全的隔離。
另一方面提供一種機制是將虛擬機的 Guest Physical Address 翻譯為物理機的 Host Physical Address。從而虛擬機訪問自己的地址就是直接訪問宿主機分配給網卡的地址。
IOMMU 硬件單元
DMA Remapping Feature 的工作是通過 CPU 硬件平臺的 IOMMU(I/O MMU,Input/Output Memory Management Unit,I/O 內存管理硬件單元)來完成的。IOMMU 的出現,實現了地址空間上的隔離,使設備只能訪問規定的內存區域。
Intel VT-d 和 AMD-Vi 都是 IOMMU 的一種硬件實現:
Intel VT-d(Intel Virtualization Technology for Directed I/O,Intel 的直接 I/O 虛擬化):用于提高虛擬化的安全性、可靠性和 I/O 性能。
AMD-Vi(AMD’s I/O Virtualization Technology,AMD 的 I/O 虛擬化技術):作用同上。
PCI Passthrough
傳統的虛擬化方案是虛擬機通過 Hypervisor 來共享的訪問一個物理網卡,當 Hypervisor 需要處理多臺虛擬機對同一個設備的并發訪問和隔離時,Hypervisor 就成為了一個性能瓶頸。
那么,既然虛擬機可以通過 IOMMU 來訪問網卡的 DMA,那么更徹底的做法就是把整塊網卡 Passthrough(直通)給虛擬機使用,即:虛擬機繞過 Hypervisor 直接操作物理網卡。這種做法稱作 PCI Passthrough。VMware,Xen 和 KVM 都支持這種技術。
主流的網卡設備商隨即推出 SR-IOV(Single Root IO Virtualization)和 MR-IOV(Multi-Root IO Virtualization)技術,將一個 PF 硬件虛擬化為 VF,繼而一張網卡可以化作多個 PCI/PCIe 設備,并 Passthrough 使用。
值得注意的是,在一些場景中,多個 PCI 設備之間是存在協作關系的,它們互相協作組成一個功能的實體,彼此之間也需要相互訪問。而 IOMMU 對該場景中的這些設備是不適用的。
開啟 IOMMU
Kernel 開啟 IOMMU 之后就可以使用 Intel VT-d / AMD-Vi,以及 PCI Passthrough 功能了,同時還作用于應對故障及惡意行為的內存保護。
啟用 IOMMU:
確保 CPU 支持 Intel VT-d / AMD-Vi,并且已經在 BIOS 中打開。
設置內核參數:
# Intel VT-d intel_iommu=on # AMD-Vi amd_iommu=on # Both,防止 Kernel 試圖 Touching 無法 Passthrough 的設備。 iommu=pt
1
2
3
4
5
6
7
8
檢查 dmesg 以確認 IOMMU 已經被正確啟用:
$ dmesg | grep -e DMAR -e IOMMU [ 0.000000] DMAR: IOMMU enabled
1
2
UIO Framework — 用戶態網絡協議棧方案
UIO Framework Kernel Module(User Space I/O,用戶態 I/O 框架內核模塊),是 Kernel 提供的用戶態 I/O 驅動程序框架。基于 UIO Framework 可以編寫出讓數據報文繞過 Kernel Network Stack,直接進入 User Space 進行處理的內核模塊(e.g. DPDK IGB_UIO)。
但是,UIO 也有著不足之處,例如:不支持 DMA(不受 IOMMU 的保護)、中斷支持有限、需要 Root 權限運行等,所以通過 DMA 傳輸大流量數據的 I/O 設備,如:被 Passthrougth 的網卡、顯卡等設備,是無法使用 UIO Framework 的。
UIO 的實現機制是:對用戶態暴露一個文件接口,當注冊一個 UIO 設備時,就會出現一個系統文件 /dev/uioX,對該文件的讀寫就是對網卡設備的內存的讀寫。除此之外,對網卡設備的控制還可以通過 /sys/class/uio 下的各個文件的讀寫來完成。
如下圖:
mmap() 接口:用于映射設備的寄存器空間。
read() 接口:用于等待一個設備中斷。
write() 接口:用于控制中斷關閉/打開。
VFIO — VNF/CNF 的用戶態網絡協議棧方案
上述:
UIO 的作用是支持用戶態網絡協議棧,問題是不支持 DMA。
IOMMU 的作用是支持 DMA Remapping 功能,問題是無法讓多個 PCI 設備互相訪問。
VFIO(Virtual Function I/O)就是 UIO 和 IOMMU 的升級版,兼顧兩者的優點,實現了:
在 User Space 配置 IOMMU interface,繼而可以將 DMA 地址空間映射限制在用戶態進程的虛擬空間中。從而解決了 UIO 不支持 DMA 的問題。
Passthrough 的最小單元不再是某個單獨的 PCI 設備,而是分布在同一個 IOMMU Group 的所有 PCI 設備;
可見,VFIO 最大的用途就是支撐 VNF 或 CNF 場景中 Passthrough 設備的用戶態 I/O 實現。使用 VFIO 可以開發出安全的、非特權的、高性能的用戶態的網卡驅動程序。
所以,VFIO 的本質與 UIO 一樣,是一個用戶態驅動框架。
一個 VFIO 設備表現為:
用戶態呈現:一個 /dev/vfio 設備文件。
內核態呈現:一個 container 對象,一個 container 中可以包含多個 IOMMU Group。
它提供兩種基本服務:
向用戶態提供訪問硬件設備的接口。
向用戶態提供配置 IOMMU 的接口。
IOMMU Group
VFIO 是如何解決讓多個 PCI 設備即 Passthrough 有可以互相訪問的呢?換句話說:VFIO 如何讓多個 PCI 設備一起 Passthrough?
為此 VFIO 引入了 IOMMU Group 的概念:
讓若干個 VF(虛擬功能設備)同處于一個 IOMMU Group。
同時,把 IOMMU Group 作為 IOMMU 操作的最小單元。
即:一個 IOMMU Group 是將若干個 VFs 直通(Passthrough)給虛擬機的最小單位。
linux 網絡 虛擬化
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。