虛擬化技術之設備直接分配(passthrough)

1、設備直接分配技術

        如何提高虛擬化設備的性能問題是虛擬化領域長期的研究重點。如前所述,設備模擬模型會導致虛擬化性能大大下降;泛虛擬化設備模型雖然在性能上擁有一定的優勢,但由於需要修改操作系統,具有侷限性.。並且當前的兩種I/O設備虛擬化模型已無法滿足高速的數據交換需求,應運而生的就是另外一種設備虛擬化模型——設備直接分配模型。

        傳統的實現I/O虛擬化的技術中,所有的虛擬機都共享物理平臺上的硬件設備。如果物理條件好,有足夠的硬件,就可以考慮讓每個虛擬機獨佔一個物理設備,這樣無疑會提高系統的性能。把某一個設備直接分配給一個虛擬機,讓虛擬機可以直接訪問該物理設備而不需要通過虛擬機監視器或被虛擬機監視器截獲,這就是設備直接分配技術。如下圖所示爲設備直接分配的I/O模型。


         在設備直接分配模型中,虛擬機操作系統可直接擁有某一物理設備的訪問控制權限,虛擬機監視器不再幹涉其訪問操作。因此,該模型可以較大地改善虛擬化設備的性能,降低監視器程序的複雜性,易於實現,並且不需要修改操作系統,保證了高可用性。

2、設備直接分配模塊設計與實現

        設備直接分配設備模型的設計主要包括了四個部分,分別是:設備隱藏模塊、建立抽象設備模塊,客戶機N啓動模塊以及設備分配模塊。

2.1 設備隱藏子模塊設計

       在虛擬化系統中,有一個特權虛擬域domain 0,這個虛擬域會在其它所有虛擬域之前啓動,並且所有的設備都會被分配給這個domain 0,再由domain 0去分配和管理。而domain 0除了接管這些設備外還可以使用這些設備。Linux操作系統在啓動設備的時候會檢測是否存在相關驅動,若存在,則使用這個驅動。設備直接分配技術的關鍵點在於,設備被一個虛擬機獨佔,其他虛擬機不能夠使用這個設備。因此會存在一個問題:如果domain 0裏有這個設備的驅動便會佔領該設備,那麼如何再將設備分配給本來想分配的虛擬機呢?

        隱藏設備的意義便是在於讓domain 0接管設備但是不使用設備,在xen中提供了一個pciback模塊,這個模塊用於對設備進行隱藏。由於Linux裏面的設備驅動是有優先級的,當一個設備存在多個不同的驅動可以使用時,Linux只會爲設備加載優先級最高的那個驅動,而pciback正是具有最高優先級的驅動,所以Linux默認會爲設備加載pciback作爲驅動。pciback模塊本身並不是一個真正的驅動,它只是起到對設備的一個接管作用,保證設備不被其他的設備驅動所佔領。

設備隱藏的實現方式有兩種:

(1)啓動時的隱藏:PCIBACK模塊提供了一個內核參數,稱爲pcibackhide。它的格式如下:

pciback. hide=(busdevicefunction)(domainbusdevicefunction) 其中busdevicefunction分別代表需要隱藏的設備的總線號、設備號、功能號。

(2)啓動後的隱藏:

        在xen啓動後,並且加載了pciback模塊之後才能夠進行。加載之後會存在一個文件夾/sys/bus/pci/drivers/pciback。在這個文件夾下面會出現3個文件:

new_slot:把設備的BDF(按照busdevicefunction格式)寫入到這個文件,告知PCIBACK模塊該設備需要被隱藏,做好相關工作。

bind:當new_slot存在設備的BDF後,再把設備的BDF(格式同上)寫入到這個文件,就可以實現對設備的隱藏。

unbind:當客戶機銷燬後,把對應客戶機的設備的BDF寫入到這個文件,那麼該設備就又可以由客戶機0使用了。

目前使用的較多的還是後者。

2.2 建立抽象設備子模塊設計

       建立抽象設備子模塊又可以分爲三個部分:初始化設備鏈表、建立抽象設備以及完成BAR(Base Address Register)映射。

QEMU作爲一個模擬軟件本身是運行在用戶態,初始化設備就是把平臺上所有的PCI設備報告給QEMU,以供接下來進行設備直接分配時使用。初始化時,首先會分配一個結構struct pci_access該結構裏面包含一個指針devices,它指向一個PCI設備鏈表,等到抽象設備初始化完成後,該指針就指向了平臺上所有的PCI設備組成的鏈表的表頭,然後再把得到的struct pci_access結構的地址賦值給QEMU的全局結構變量dpci_infospci_access成員,這樣PCI設備鏈表的初始化就完成了。當以後向客戶機直接分配物理設備時,QEMU就能夠通過查找此鏈表完成後續工作。

       在完成設備鏈表的初始化後,就可以向虛擬機分配設備,QEMU會根據設備的BDF來查詢設備鏈表,如果能找到對應的設備,則認爲是直接分配,否則會採用設備模擬的方式來完成。目前來說,直接分配設備通常都是通過在虛擬機的配置文件裏面寫入設備的BDF來實現。在啓動虛擬機時,首先會去讀取虛擬機的配置文件,若存在這些BDF則採用直接分配的方式分配設備,並且如果有多個設備,彼此之間用逗號隔開。

        QEMU爲抽象設備分配虛擬PCI BAR後,再通過設備鏈表獲得物理設備的BAR,最後再來完成抽象設備和物理設備之間映射的建立。QEMU在通過超調用把需要建立PCI BAR映射的相關信息報告給虛擬機監視器後,監視器將根據獲得的信息來建立轉換表,至此,QEMU就完成了它的工作,整個抽象設備在QEMU裏面的建立也就完畢了

2.3客戶機N啓動子模塊

       這個模塊主要是完成I/O端口轉換表和MMIO轉換表的建立過程。

       通過把虛擬機的ID,虛擬機的虛擬端口號,真實的設備端口號以及端口數量等信息報告給虛擬機監視器,交由虛擬機監視器來建立I/O端口轉換表。建立和解除端口轉換表的都是同一個超級調用,如果被虛擬機監視器截獲後判斷是建立I/O端口轉換表映射關係時,會去遍歷原來的端口轉換表,查看是否已經存在與該設備之間的映射,如果存在則更新虛擬端口,如不存在則建立映射關係。在建立好I/O端口轉換表後,下次虛擬機再通過虛擬端口訪問設備,被虛擬機監視器截獲後就可以通過轉換表找到真正的物理端口了。

      建立MMIO轉換表的過程與建立I/O轉換表的過程類似,都是通過超級調用,被虛擬機監視器截獲後,會判斷是否建立MMIO轉換表映射關係,如果是,則會根據虛擬機的ID去查找對應的客戶機物理地址與機器物理地址轉換關係表,簡稱P2M表,遍歷該表,找到對應的MMIO的內存地址所在項,把機器物理地址寫入。映射建立完成後,當虛擬機發起MMIO訪問時就可以直接找到對應的機器物理地址

2.4 設備分配模塊

    在設備隱藏子模塊中,爲防止設備被佔用,設備被交由domain 0所接管,而在這個模塊中要負責完成設備的分配過程。設備分配的操作也是一個超級調用,被虛擬機監視器截獲後會根據虛擬機的ID以及在虛擬機的配置文件中所讀取到的設備的BDF來完成設備的分配過程,主要是解除設備與domain 0的一個映射關係,然後建立起設備與被分配到的虛擬機之間的映射關係。

3、設備直接分配技術的使用


下面以Xen平臺爲例介紹如何把一個設備直接分配給一個虛擬機。
(1)老版本的內核注意開啓IOMMU,在grub中加入對應的啓動參數項
title Xen-Linux (2.6.18-xen) 
 root (hd0,0) kernel /boot/xen.gz iommu=1 
 module /boot/vmlinuz-2.6.18.8-xen root=LABEL=/ 
 module /boot/initrd-2.6.18-xen.img


(2)用lspci命令查看要直接分配的設備的BDF號

[root@localhost ~]# lspci |grep 'Eth'
01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
01:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)


(3)將設備隱藏,例如一個BDF爲08:00.0的設備

echo 0000:08:00.0 > /sys/bus/pci/devices/0000:08:00.0/driver/unbind

echo 0000:08:00.0 > /sys/bus/pci/drivers/pciback/new_slot

echo 0000:08:00.0 > /sys/bus/pci/drivers/pciback/bind


(4)查看可直接分配的設備

# xm pci-list-assignable-devices

08:00.0

如果是xl命令,那麼查看的命令如下:

# xl pci-assignable-list

08:00.0


(5)將設備直接分配給虛擬機

修改虛擬機的配置文件,加上下面一行,如果有多個分給該虛擬機的設備,用逗號隔開

pci=['08:00.0','08:00.1']





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