DPDK support for vhost-user(二十七)

X86體系早期沒有在硬件設計上對虛擬化提供支持,因此虛擬化完全通過軟件實現。一個典型的做法是通過優先級壓縮(Ring Compression)和二進制代碼翻譯(Binary Translation)相結合,VMM在特權級ring 0, Guest操作系統在非特權級ring 1, Guest應用程序在ring 3。 由於Guest操作系統工作在非特權級ring 1中,這樣當它執行特權指令時就會觸發異常,由VMM截獲異常並採用軟件方式模擬指令並返回。 但由於X86體系在設計之初沒有考慮虛擬化,所以一小部分特權指令在ring 1下沒有引發異常,所以需要對操作系統的二進制代碼進行掃描,一旦發現不友好的指令,將就其換成支持虛擬化的指令塊,這些指令塊與VMM合作訪問受限的虛擬資源,或者顯式地觸發異常讓VMM進一步處理。這種打補丁的方式很難在構架上保證其完整性。於是,下層的硬件加入了虛擬化功能,硬件截獲操作系統對敏感指令的執行或者對敏感資源的訪問後通過異常的方式報告給VMM,這樣就解決了虛擬化的問題。Intel VTx技術是這一方向的代表,它引入了一個新的特殊執行模式用於運行虛擬機,這個模式會將特權指令統統截取並報告給VMM,VMM本身工作在正常模式下,在接收到處理的報告後,通過對目標指令的解碼,找到相應的虛擬化模塊進行模擬。

對於內存的虛擬化則需要**用硬件實現從GVA(Guest Virtual Address)到GPA(Guest Physical Address)再到HPA(Host Physical Address)的兩次地址轉換。**傳統非虛擬化的操作系統只通過硬件MMU完成一次從GVA到GPA的虛擬化。

I/O的虛擬化方面,VTd技術在北橋引入DMA重映射硬件來提供設備重映射和設備直接分配的功能。設備所有的DMA傳輸都會被DMA重映射硬件截取,然後根據設備對應的I/O頁表,對DMA中的地址進行轉換,使設備只能訪問特定的內存。這樣,設備就可以直接分配給Guest機使用,驅動提供給設備的GPA經過重映射,變爲HPA,使得DMA操作得以完成。

在網絡虛擬化方面,VTd技術可以將一個物理網卡直接分配給一個虛機使用,但擴展性差,因爲一臺服務支持的PCI設備數是有限的,遠遠不能滿足越來越來的Guest機數量。因此SRIOV(Single Root I/O Virtualization)被引入來解決這個問題。SRIOV是PCIe(PCI Express)規範的一個擴展,定義了本質上可以共享的設備。它允許一個PCIe設備,通過是網卡,爲每個與其相連的客戶機複製一份資源(例如內存資源、中斷和DMA數據流),使得數據處理不再依賴VMM。

GPU虛擬化方面,如XenGT,它是由Intel在Xen基礎上開發的GPU虛擬化開源方案。客戶機操作系統不需要任何改動,特權操作會被Xen截獲,並且轉發到中介(Mediator),中介爲每個客戶機創建一個GPU上下文(Context),並且在其中模擬特權操作。

1、普通虛擬化

傳統的KVM實現中,kvm.ko是內核的一個模塊主要用來捕獲虛機的是上述的針對CPU、內存MMU的特權指令然後負責模擬,對I/O的模擬則是再通過用戶態的Qemu進程模擬的,Qemu負責解釋I/O指令流,並通過系統調用讓Host操作系統上的驅動去完成真正的I/O操作。這其中用戶態與內核態切換了兩次,數據也需要複製。
在這裏插入圖片描述
用戶態的Qemu在啓動Guest操作系統時,可以先通過KVM在用戶態的字符接口/dev/kvm獲取Guest的地址空間(fd_vm)和KVM本身(fd_kvm),然後通過fd_vm將Guest的物理空間mmap到Qemu進程的虛擬空間(虛機就是一個進程,虛機進程的用戶虛擬空間就是Guest的物理空間,映射之後Qemu的虛擬設備就可以很方便的存取Guest地址空間裏的數據了),並根據配置信息創建vcpu[N]線程(對虛機來說,虛機進程的線程對應着Guest的處理器),然後Qemu將操作fd_vcpu[N]在自己的進程空間mmap一塊KVM的數據結構區域(即下圖的shared,包括:Guest的IO信息,如端口號,讀寫方向,內存地址)。該數據結構用於Qemu和kvm.ko交互,Qemu通過它調用虛擬設備註冊的回調函數來模擬設備的行爲,並將Guest IO的請求換成系統請求發給Host系統。

圖中vm-exit代表處理器進入host模式,執行kvm和Qemu的邏輯。vm-entry代表處理器進入Guest模式,執行整個Guest系統的邏輯。Qemu通過三個文件描述符同kvm.ko交互,然後kvm.ko通過vmcs這個數據結構同處理器交互,最終達到控制Guest系統的效果。其中fd_kvm主要用於Qemu同KVM本身的交互,比如獲取KVM的版本號,創建地址空間、vcpu等。fd_vcpu主要用於控制處理器的模式切換,設置進入Guest mode前的處理器狀態等等(內存尋址模式,段寄存器、控制寄存器、指令指針等),同時Qemu需要通過fd_vcpu來mmap一塊KVM的數據結構區域。fd_vm主要用於Qemu控制Guest的地址空間,向Guest注入虛擬中斷等。
在這裏插入圖片描述
2、VirtIO

VirtIO通過共享內存的方式爲Guest和Qemu提供了高速的硬盤與網絡I/O通道(因爲Guest的地址空間早就mmap到Qemu的進程空間)。VirtIO只需要增加VirtIO Driver和VirtIO Device即可直接讀寫共享內存。如下圖,Guest VirtIO驅動通過訪問port地址空間向Qemu的VirtIO設備發送IO發起消息。而設備通過讀寫irqfd或者IOCTL fd_vm將I/O的完成情況通知給Guest的驅動。irqfd和ioeventfd是KVM爲用戶程序基於內核eventfd機制提供的通知機制,以實現異步的IO處理(這樣發起IO請求的vcpu將不會阻塞)。之所以使用PIO而不是MMIO,是因爲KVM處理PIO的速度快於MMIO。
在這裏插入圖片描述
3、vhost

VirtIO通過共享內存減小了Guest與Qemu之間數據複製的開銷,但Qemu到內核的系統調用還是跑不了。有必要將模擬I/O的邏輯將VirtIO Device挪到內核空間避免系統調用。

vhost在內核態再增加一個vhost-net.ko模塊, vhost client與vhost backend通過共享內存(virtqueues, unit socket), 文件描述符(ioeventfds), (中斷號)irqfds實現快速交換數據的機制。
在這裏插入圖片描述

4、vhost-user

vhost使用了內核態TCP/IP棧導致從Guest到kvm.ko仍然有一個用戶態內核態的切換以及數據的拷貝。一些用戶態棧議棧如openonload直接在用戶態實現網卡驅動再實現BSD兼容的socket接口供上層應用使用,vhost-user(需要將vhost-backend移到用戶態)的共享內存技術用於將這些用戶態網絡設備(又如snabb switch)和用戶態的Guest連接起來

5、DPDK support for vhost-user [3]

DPDK便是一個在用戶態可以直接操作物理網卡的庫函數,它和vhost-user結合便可以實現類似於snabb switch一樣性能強勁的用戶態交換機了。2015年6月16日dpdk vhost-user ports特性合併到了ovs社區[1], dpdkvhostuser port將創建unix socket將虛機的virtio-net虛擬網卡的網卡緩衝區共享給物理機上的ovs port設備。

原文鏈接:https://blog.csdn.net/quqi99/article/details/47321023?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159379937319725219931004%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=159379937319725219931004&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_blog_default-2-47321023.pc_v2_rank_blog_default&utm_term=dpdk

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章