1. 程式人生 > >VIRTIO概述和基本原理

VIRTIO概述和基本原理

http://smilejay.com/2012/11/virtio-overview/

(KVM連載)5.1.1 VIRTIO概述和基本原理(KVM半虛擬化驅動)

11/15/2012

5.1 半虛擬化驅動

5.1.1 virtio概述

KVM是必須使用硬體虛擬化輔助技術(如Intel VT-x、AMD-V)的hypervisor,在CPU執行效率方面有硬體支援,其效率是比較高的;在有Intel EPT特性支援的平臺上,記憶體虛擬化的效率也較高。QEMU/KVM提供了全虛擬化環境,可以讓客戶機不經過任何修改就能執行在KVM環境中。不過,KVM在I/O虛擬化方面,傳統的方式是使用QEMU純軟體的方式來模擬I/O裝置(如第4章中提到模擬的網絡卡、磁碟、顯示卡等等),其效率並不非常高。在KVM中,可以在客戶機中使用半虛擬化驅動(Paravirtualized Drivers,PV Drivers)來提高客戶機的效能(特別是I/O效能)。目前,KVM中實現半虛擬化驅動的方式是採用了virtio這個Linux上的裝置驅動標準框架。

1. QEMU模擬I/O裝置的基本原理和優缺點

QEMU純軟體方式模擬現實世界中的I/O裝置的基本過程模型如圖5-1所示。

 

qemu-emulated-io-device

qemu-emulated-io-device

圖5-1 QEMU 模擬I/O裝置

使用QEMU模擬I/O的情況下,當客戶機中的裝置驅動程式(device driver)發起I/O操作請求之時,KVM模組中的I/O操作捕獲程式碼會攔截這次I/O請求,然後經過處理後將本次I/O請求的資訊存放到I/O共享頁,並通知使用者控制元件的QEMU程式。QEMU模擬程式獲得I/O操作的具體資訊之後,交由硬體模擬程式碼來模擬出本次的I/O操作,完成之後,將結果放回到I/O共享頁,並通知KVM模組中的I/O操作捕獲程式碼。最後,由KVM模組中的捕獲程式碼讀取I/O共享頁中的操作結果,並把結果返回到客戶機中。當然,這個操作過程中客戶機作為一個QEMU程序在等待I/O時也可能被阻塞。另外,當客戶機通過DMA(Direct Memory Access)訪問大塊I/O之時,QEMU模擬程式將不會把操作結果放到I/O共享頁中,而是通過記憶體對映的方式將結果直接寫到客戶機的記憶體中去,然後通過KVM模組告訴客戶機DMA操作已經完成。

QEMU模擬I/O裝置的方式,其優點是可以通過軟體模擬出各種各樣的硬體裝置,包括一些不常用的或者很老很經典的裝置(如4.5節中提到RTL8139的網絡卡),而且它不用修改客戶機作業系統,就可以實現模擬裝置在客戶機中正常工作。在KVM客戶機中使用這種方式,對於解決手上沒有足夠裝置的軟體開發及除錯有非常大的好處。而它的缺點是,每次I/O操作的路徑比較長,有較多的VMEntry、VMExit發生,需要多次上下文切換(context switch),也需要多次資料複製,所以它的效能較差。

2. Virtio的基本原理和優缺點

Virtio最初由澳大利亞的一個天才級程式設計師Rusty Russell編寫,是一個在hypervisor之上的抽象API介面,讓客戶機知道自己執行在虛擬化環境中,從而與hypervisor根據 virtio 標準協作,從而在客戶機中達到更好的效能(特別是I/O效能)。目前,有不少虛擬機器都採用了virtio半虛擬化驅動來提高效能,如KVM和Lguest[1]。

QEMU/KVM中,Virtio的基本結構框架如圖5-2所示。

 

qemu-kvm-virtio-arch

qemu-kvm-virtio-arch

圖5-2 KVM中virtio基本架構

其中前端驅動(frondend,如virtio-blk、virtio-net等)是在客戶機中存在的驅動程式模組,而後端處理程式(backend)是在QEMU中實現的[2]。在這前後端驅動之間,還定義了兩層來支援客戶機與QEMU之間的通訊。其中,“virtio”這一層是虛擬佇列介面,它在概念上將前端驅動程式附加到後端處理程式。一個前端驅動程式可以使用0個或多個佇列,具體數量取決於需求。例如,virtio-net網路驅動程式使用兩個虛擬佇列(一個用於接收,另一個用於傳送),而virtio-blk塊驅動程式僅使用一個虛擬佇列。虛擬佇列實際上被實現為跨越客戶機作業系統和hypervisor的銜接點,但它可以通過任意方式實現,前提是客戶機作業系統和virtio後端程式都遵循一定的標準,以相互匹配的方式實現它。而virtio-ring實現了環形緩衝區(ring buffer),用於儲存前端驅動和後端處理程式執行的資訊,並且它可以一次性儲存前端驅動的多次I/O請求,並且交由後端去動去批量處理,最後實際呼叫宿主機中裝置驅動實現物理上的I/O操作,這樣做就可以根據約定實現批量處理而不是客戶機中每次I/O請求都需要處理一次,從而提高客戶機與hypervisor資訊交換的效率。

Virtio半虛擬化驅動的方式,可以獲得很好的I/O效能,其效能幾乎可以達到和native(即:非虛擬化環境中的原生系統)差不多的I/O效能。所以,在使用KVM之時,如果宿主機核心和客戶機都支援virtio的情況下,一般推薦使用virtio達到更好的效能。當然,virtio的也是有缺點的,它必須要客戶機安裝特定的Virtio驅動使其知道是執行在虛擬化環境中,且按照Virtio的規定格式進行資料傳輸,不過客戶機中可能有一些老的Linux系統不支援virtio和主流的Windows系統需要安裝特定的驅動才支援Virtio。不過,較新的一些Linux發行版(如RHEL 6.3、Fedora 17等)預設都將virtio相關驅動編譯為模組,可直接作為客戶機使用virtio,而且對於主流Windows系統都有對應的virtio驅動程式可供下載使用。