I/O虛擬化是SmartNIC/DPU/IPU中最核心的部分,AWS NITRO就是從I/O硬件虛擬化開始,逐漸開啟了DPU這個(gè)新處理器類型的創(chuàng)新。而Virtio接口,已經(jīng)是事實(shí)上的云計(jì)算虛擬化的標(biāo)準(zhǔn)化接口。Virtio成為整個(gè)問(wèn)題的焦點(diǎn):不管是SPDK/vhost、還是vDPA加速,都是圍繞著Virtio接口展開。
本文圍繞I/O設(shè)備虛擬化、通用接口Virtio以及虛擬化卸載等方面進(jìn)行了詳細(xì)的解讀。推薦給大家。
**01 **I/O設(shè)備虛擬化:從軟件模擬到SR-IOV
I/O虛擬化是計(jì)算機(jī)虛擬化最復(fù)雜的部分,因?yàn)樯婕暗?a href="http://wenjunhu.com/v/tag/132/" target="_blank">CPU、操作系統(tǒng)、Hypervisor以及I/O設(shè)備的相互配合。I/O虛擬化也經(jīng)歷了從軟件模擬虛擬化、類虛擬化向完全硬件虛擬化的轉(zhuǎn)變。
a. I/O軟件模擬虛擬化和類虛擬化
I/O設(shè)備虛擬化場(chǎng)景,既要關(guān)注I/O設(shè)備模擬,也要關(guān)注vCPU和虛擬I/O設(shè)備的交互,許多條件交織在一起,使得整個(gè)問(wèn)題變的非常復(fù)雜。I/O虛擬化性能代價(jià)主要體現(xiàn)在三個(gè)方面:驅(qū)動(dòng)訪問(wèn)設(shè)備寄存器的代價(jià);設(shè)備通過(guò)中斷和DMA訪問(wèn)驅(qū)動(dòng)的代價(jià);設(shè)備模擬本身的代價(jià)。因此,I/O虛擬化性能優(yōu)化主要是通過(guò)五個(gè)角度:
- 減少I/O訪問(wèn)寄存器的代價(jià):一方面是把部分I/O的訪問(wèn)變成MMIO訪問(wèn),這樣就不需要陷入Hypervisor;另一方面是優(yōu)化VM-exit/VM-entry切換的代價(jià)。
- 減少I/O訪問(wèn)的次數(shù):比如簡(jiǎn)化通知機(jī)制,簡(jiǎn)化虛擬化設(shè)備功能等。
- 優(yōu)化中斷:主要有如APIC的中斷硬件虛擬化或者不需要中斷的輪詢驅(qū)動(dòng)。
- 減少DMA訪問(wèn)的代價(jià):通過(guò)IOMMU等實(shí)現(xiàn)Pass Through模式。
- 減少設(shè)備模擬的代價(jià):則主要是通過(guò)硬件SR-IOV機(jī)制實(shí)現(xiàn)硬件設(shè)備。
如圖1(a),虛擬機(jī)中看到的設(shè)備,一般是由Hypervisor模擬出來(lái)的。虛擬設(shè)備的功能,可以少于也可以多于物理的設(shè)備,甚至可以模擬出一些不存在的特性,模擬出不存在的硬件設(shè)備。通過(guò)I/O軟件模擬的方式,我們稱之為I/O設(shè)備軟件模擬虛擬化。在I/O軟件模擬虛擬化的解決方案中,客戶機(jī)VM要使用底層的硬件資源,需要Hypervisor來(lái)截獲每一條請(qǐng)求指令,然后模擬出這些指令的行為。我們都知道Hypervisor截獲指令的動(dòng)作就是從VM-exit,處理完模擬然后再VM-entry的過(guò)程,這個(gè)過(guò)程的代價(jià)很高,每條指令都要如此,帶來(lái)的性能開銷必然是非常龐大的。
如圖1(b)所示,Virtio提供的類虛擬化方式,客戶機(jī)完成設(shè)備的前端驅(qū)動(dòng)程序,Hypervisor配合客戶機(jī)完成相應(yīng)的后端驅(qū)動(dòng)程序,這樣兩者之間通過(guò)交互機(jī)制就可以實(shí)現(xiàn)高效的虛擬化過(guò)程。
圖1 I/O設(shè)備虛擬化
Virtio框架如圖2所示,使用Virtqueue來(lái)實(shí)現(xiàn)其I/O機(jī)制,每個(gè)Virtqueue就是一個(gè)承載大量數(shù)據(jù)的Queue。VRing是Virtqueue的具體實(shí)現(xiàn)方式,針對(duì)VRing會(huì)有相應(yīng)的描述符表格進(jìn)行描述。Virtio是一個(gè)通用的驅(qū)動(dòng)和設(shè)備接口框架,基于Virtio分別實(shí)現(xiàn)了Virtio-net、Virtio-blk、Virtio-scsi等很多不同類型的模擬設(shè)備及設(shè)備驅(qū)動(dòng)。
圖2 Virtio框架
Virtio類虛擬化比傳統(tǒng)的I/O設(shè)備軟件模擬的性能優(yōu)勢(shì)體現(xiàn)在:很多控制和狀態(tài)信息不需要通過(guò)寄存器讀寫操作來(lái)交互的,而是通過(guò)寫入Virtqueue的相關(guān)數(shù)據(jù)結(jié)構(gòu)來(lái)讓驅(qū)動(dòng)(Driver)和設(shè)備(Device)雙方交互。并且在數(shù)據(jù)交互的時(shí)候,只需要在一定批量數(shù)據(jù)變化需要對(duì)方處理的時(shí)候才會(huì)通知對(duì)方,驅(qū)動(dòng)通知設(shè)備是通過(guò)寫Kick寄存器,設(shè)備通知驅(qū)動(dòng)是通過(guò)中斷。
b. I/O完全硬件虛擬化
評(píng)價(jià)I/O虛擬化技術(shù)的兩個(gè)指標(biāo)——性能和通用性。性能,當(dāng)然是越接近無(wú)虛擬化環(huán)境下的I/O性能最好;而通用性,則是I/O虛擬化對(duì)客戶操作系統(tǒng)越透明越好。要想要高性能,最直接的方法就是讓客戶機(jī)直接使用真實(shí)的硬件設(shè)備;要想要通用性,則是要用想辦法讓客戶機(jī)操作系統(tǒng)自帶的驅(qū)動(dòng)程序能夠發(fā)現(xiàn)設(shè)備并操作設(shè)備。
客戶機(jī)直接操作設(shè)備面臨兩個(gè)問(wèn)題:第一,如何讓客戶機(jī)直接訪問(wèn)到設(shè)備真實(shí)的I/O地址空間(包括I/O和MMIO);第二,如何讓設(shè)備的DMA直接訪問(wèn)客戶機(jī)的內(nèi)存空間。內(nèi)存硬件虛擬化的EPT技術(shù)可以解決第一個(gè)問(wèn)題。而VT-d技術(shù)則用來(lái)解決第二個(gè)問(wèn)題。VT-d技術(shù)主要是引入地址重映射(IOMMU+IOTLB),負(fù)責(zé)提供重映射和設(shè)備直接分配。從設(shè)備端的DMA訪問(wèn),都會(huì)進(jìn)入地址重映射進(jìn)行地址轉(zhuǎn)換,使得設(shè)備可以訪問(wèn)到對(duì)應(yīng)客戶機(jī)特定的內(nèi)存區(qū)域。
VT-d技術(shù)雖然可以將物理的I/O設(shè)備直接透?jìng)鹘o虛擬機(jī),但是一臺(tái)計(jì)算機(jī)系統(tǒng)受限于接口,可以連的物理設(shè)備畢竟有限。因此,PCIe SR-IOV技術(shù)應(yīng)運(yùn)而生。通過(guò)PCIe SR-IOV技術(shù),一個(gè)物理I/O設(shè)備可以虛擬出多個(gè)虛擬設(shè)備,分配給虛擬機(jī)使用。
如圖1(c)所示,SR-IOV引入了兩個(gè)PCIe的功能類型:
- PFs(Physical Functions):包括管理SR-IOV功能在內(nèi)的所有PCIe設(shè)備。
- VFs(Virtual Functions):輕量級(jí)的PCIe設(shè)備,只能進(jìn)行必要的配置和數(shù)據(jù)傳輸。
Hypervisor把VF分配給虛擬機(jī),通過(guò)IOMMU等硬件輔助技術(shù)提供的DMA數(shù)據(jù)映射,直接在虛擬機(jī)和硬件設(shè)備之間傳輸數(shù)據(jù)。
c. I/O虛擬化總結(jié)
通過(guò)兼容性、性能、成本、擴(kuò)展性四個(gè)方面對(duì)I/O虛擬化技術(shù)進(jìn)行總結(jié),詳見表1:
表1 不同I/O虛擬化方式對(duì)比
I/O虛擬化方式 | VM的兼容性 | 性能 | 成本 | 擴(kuò)展性 |
---|---|---|---|---|
設(shè)備接口軟件模擬 | 重用已有驅(qū)動(dòng) | 頻繁的上下文切換 | 沒(méi)有額外硬件成本 | 受設(shè)備模擬的性能代價(jià)約束 |
類虛擬化前后端 | 需要加載特定驅(qū)動(dòng) | 基于共享隊(duì)列的機(jī)制減少了前后端交互 | 沒(méi)有額外硬件成本 | 受設(shè)備后端的性能代價(jià)約束 |
直接分配VT-d | 重用設(shè)備驅(qū)動(dòng) | 直接訪問(wèn)物理設(shè)備,減少虛擬化開銷 | 需要購(gòu)買額外的較多的硬件 | 硬件設(shè)備獨(dú)占性,受主板擴(kuò)展槽限制 |
直接分配SR-IOV | 需要加載VF驅(qū)動(dòng) | 直接訪問(wèn)物理設(shè)備,減少虛擬化開銷 | 需要購(gòu)買額外的較少的硬件 | 硬件設(shè)備支持多個(gè)虛擬設(shè)備,擴(kuò)展性較好 |
**02 **通用接口Virtio
Virtio旨在提供一套高效的、良好維護(hù)的通用的Linux驅(qū)動(dòng),實(shí)現(xiàn)虛擬機(jī)應(yīng)用和不同Hypervisor實(shí)現(xiàn)的模擬設(shè)備之間標(biāo)準(zhǔn)化的接口。Virtio作為類虛擬化的I/O設(shè)備接口,廣泛應(yīng)用于云計(jì)算虛擬化場(chǎng)景,某種程度上,Virtio已經(jīng)成為事實(shí)上的I/O設(shè)備的接口標(biāo)準(zhǔn)。
在上一節(jié)介紹I/O虛擬化時(shí),Virtio作為I/O類虛擬化技術(shù)做過(guò)介紹。本節(jié)會(huì)略去虛擬化相關(guān)的內(nèi)容,把Virtio作為一個(gè)標(biāo)準(zhǔn)的接口進(jìn)行詳細(xì)的闡述。
2.1 Virtio寄存器
Virtio寄存器有三種類型:設(shè)備狀態(tài)字、功能特征位以及PCIe配置空間。
a. 設(shè)備狀態(tài)字
如表2所示,設(shè)備狀態(tài)字(Device Status Field)標(biāo)識(shí)了初始化序列步驟的完成情況。
表2 設(shè)備狀態(tài)字描述
Bit位置 | 狀態(tài)字值 | 定義 | 描述 |
---|---|---|---|
0 | 1 | ACKNOWLEDGE | 表示操作系統(tǒng)已找到該設(shè)備并將其識(shí)別為有效的Virtio設(shè)備 |
1 | 2 | DRIVER | 表示操作系統(tǒng)已找到該設(shè)備并將其識(shí)別為有效的Virtio設(shè)備 |
2 | 4 | DRIVER_OK | 表示已安裝驅(qū)動(dòng)程序并準(zhǔn)備驅(qū)動(dòng)設(shè)備 |
3 | 8 | FEATURES_OK | 表示驅(qū)動(dòng)程序已確認(rèn)其理解的所有功能,并且功能協(xié)商已完成 |
4 | 16 | 保留位 | 保留位 |
5 | 32 | 保留位 | 保留位 |
6 | 64 | DEVICE_NEEDS_RESET | 表示設(shè)備遇到了無(wú)法恢復(fù)的錯(cuò)誤。 |
7 | 128 | FAILED | 表示操作系統(tǒng)出現(xiàn)問(wèn)題,或者驅(qū)動(dòng)和設(shè)備功能不匹配,或者設(shè)備運(yùn)行過(guò)程中出現(xiàn)致命錯(cuò)誤等。 |
基于設(shè)備狀態(tài)字,Virtio協(xié)議定義并約束了驅(qū)動(dòng)程序必須按照以下順序初始化設(shè)備:
(1)重置設(shè)備。
(2)設(shè)置ACKNOWLEDGE狀態(tài)位,表示OS已發(fā)現(xiàn)此設(shè)備。
(3)設(shè)置DRIVER狀態(tài)位,表示OS知道如何驅(qū)動(dòng)此設(shè)備。
(4)讀取設(shè)備功能位,并將操作系統(tǒng)和驅(qū)動(dòng)程序可以理解的功能位子集寫入設(shè)備。
(5)設(shè)置FEATURES_OK狀態(tài)位。
(6)重新讀取設(shè)備狀態(tài),如果FEATURES_OK讀取結(jié)果依然為1,則表示設(shè)備接受了驅(qū)動(dòng)的功能位子集;否則,如果為0,則表示該設(shè)備不支持驅(qū)動(dòng)的功能子集,該設(shè)備不可用。
(7)執(zhí)行設(shè)備特定的設(shè)置,包括發(fā)現(xiàn)設(shè)備的虛擬隊(duì)列、讀取和可能寫入設(shè)備的virtio配置空間以及填充虛擬隊(duì)列等。
(8)將DRIVER_OK狀態(tài)位設(shè)置為1。此時(shí),設(shè)備初始化完成,設(shè)備處于活動(dòng)狀態(tài)。
(9)如果上述這些步驟中的任何一個(gè)發(fā)生不可恢復(fù)的錯(cuò)誤,驅(qū)動(dòng)程序會(huì)將FAILED狀態(tài)位設(shè)置為1。
b. 功能特征位
每個(gè)Virtio設(shè)備均提供其支持的所有功能對(duì)應(yīng)的功能特征位。在設(shè)備初始化期間,驅(qū)動(dòng)程序?qū)⒆x取此信息并告知設(shè)備它接受的子集。
通過(guò)這種方式可以實(shí)現(xiàn)向前和向后兼容:如果設(shè)備增加了新功能位,則較舊的驅(qū)動(dòng)程序就不會(huì)將該功能位寫回到設(shè)備中(意味著此功能不會(huì)被開啟)。同樣,如果驅(qū)動(dòng)程序增加了新的功能,而設(shè)備未提供此功能,則同樣此功能不會(huì)被寫回到設(shè)備(意味著此功能不會(huì)被開啟)。
Virtio1.1協(xié)議中的功能位分配如下:
- 比特位0 – 23:特定設(shè)備類型的功能位;
- 比特位24 – 37:保留用于擴(kuò)展隊(duì)列和功能協(xié)商機(jī)制的功能位;
- 比特位38以上:保留功能位以供將來(lái)擴(kuò)展。
c. 配置空間
Virtio over PCI使用的配置空間與標(biāo)準(zhǔn)的PCI配置空間相比,特殊的地方在于其Vendor ID和Device ID。Virtio的Vendor ID為0x1AF4,其Device ID編號(hào)從0x1040-0x107F。
為了跟PCI Capabilities格式兼容,Virtio定義的virtio_pci_cap格式如表3所示。
表3 Virtio的PCI capability結(jié)構(gòu)
Byte 3 | Byte 2 | Byte 1 | Byte 0 | |
---|---|---|---|---|
0x0 | cfg_type | cap_len | cap_vndr | cap_vndr |
0x4 | padding | bar | ||
0x8 | offset | |||
0xC | Length |
其中cfg_type標(biāo)識(shí)virtio_pci_cap類型,共有五種,代表了映射在BAR空間的五組寄存器。virtio_pci_cap類型如表4所示。
表4 Virtio PCI capability類型
類型名稱 | ID | 描述 |
---|---|---|
VIRTIO_PCI_CAP_COMMON_CFG | 1 | 通用配置 |
VIRTIO_PCI_CAP_NOTIFY_CFG | 2 | 通知 |
VIRTIO_PCI_CAP_ISR_CFG | 3 | ISR狀態(tài) |
VIRTIO_PCI_CAP_DEVICE_CFG | 4 | 設(shè)備具體的配置 |
VIRTIO_PCI_CAP_PCI_CFG | 5 | PCI配置訪問(wèn) |
-
接口
+關(guān)注
關(guān)注
33文章
8605瀏覽量
151191 -
DPU
+關(guān)注
關(guān)注
0文章
358瀏覽量
24184 -
i/o
+關(guān)注
關(guān)注
0文章
33瀏覽量
4593
相關(guān)推薦
評(píng)論