隨著計(jì)算機(jī)硬件的發(fā)展,人們對(duì)最大化利用硬件資源的需求日益迫切。從上世紀(jì)六、七十年代虛擬機(jī)概念的提出,到現(xiàn)在虛擬化技術(shù)的日益成熟,為人們這些需求的實(shí)現(xiàn)提供了有利的解決方案。基于IntelVT技術(shù)的KVM虛擬機(jī),是一種采用硬件輔助虛擬化的全虛擬化方案,并在Linux 內(nèi)核版本2.6.20 之后,以模塊的形式集成到內(nèi)核的各個(gè)主要發(fā)行版本。KVM虛擬機(jī)吸收了QEMU、Bochs、UML、Virtual PC 等傳統(tǒng)虛擬機(jī)的長(zhǎng)處和優(yōu)勢(shì),利用硬件輔助的虛擬化技術(shù),使虛擬機(jī)的大多數(shù)指令可以直接在物理處理器上運(yùn)行,具有更加優(yōu)越的效率和性能。為了充分利用處理器的資源,往往需要虛擬機(jī)在某一指定個(gè)核上運(yùn)行,而其它的核上運(yùn)行特定的任務(wù)。本文基于CPU 的親和性(Affinity),采用進(jìn)程綁定,實(shí)現(xiàn)了一種解決上述問(wèn)題的有效方法。
1 Intel VT技術(shù)下的KVM虛擬機(jī)架構(gòu)
KVM 虛擬機(jī)由兩部分構(gòu)成:一部分是以模塊形式集成到Linux 內(nèi)核的KVM Driver,負(fù)責(zé)管理虛擬硬件資源,并創(chuàng)建一個(gè)字符設(shè)備(/dev/kvm),通過(guò)ioctl接口與用戶空間的設(shè)備通信,以及完成虛擬機(jī)內(nèi)存的分配、虛擬機(jī)寄存器的讀寫(xiě)以及虛擬機(jī)CPU 的運(yùn)行等。因此,每個(gè)虛擬機(jī)被Linux 核心當(dāng)作是一個(gè)標(biāo)準(zhǔn)的進(jìn)程。另一個(gè)部分是KQEMU,即針對(duì)有虛擬化支持的X86 處理器而修改過(guò)的QEMU。KQEMU 主要是完成對(duì)硬件的模擬,通過(guò)/dev/kvm 與KVM Driver 交互。KVM 虛擬機(jī)架構(gòu)如圖1 所示:
在Intel VT-x 技術(shù)下有兩種工作模式:VMX rootoperation 模式和VMX non-root operation 模式。在這兩種模式下,KVM 虛擬機(jī)充分利用硬件的支持,實(shí)現(xiàn)了系統(tǒng)的虛擬化。KVM 的KVM Driver 和KQEMU分別運(yùn)行于Kernel 模式的和User 模式。這里的Kernel模式和User 模式實(shí)際上指的是VMX root operation 模式下的特權(quán)級(jí)0 和特權(quán)級(jí)3。在圖1 中,Linux Kernel、KVM Driver 和/dev/kvm 都屬于VMX root operation 模式。另外,KVM 將客戶機(jī)所在的運(yùn)行模式稱為Guest模式,即VMX 的VMX non-root operation 模式。
圖1 KVM 虛擬機(jī)架構(gòu)
2 KQEMU和KVM工作原理
Intel VT-x 是與處理器管理相關(guān)的硬件虛擬化技術(shù)[6]。在VT-x 的支持下,KVM 中的每個(gè)虛擬機(jī)可具有多個(gè)虛擬處理器VCPU,每個(gè)VCPU 對(duì)應(yīng)一個(gè)KQEMU 的線程,這個(gè)KQEMU 線程代表了KVM 虛擬機(jī)的運(yùn)行。沒(méi)有硬件支持的純QEMU 虛擬機(jī)和利用硬件支持實(shí)現(xiàn)虛擬化的KVM 虛擬機(jī)的差異也就在這里。為了更加形象地說(shuō)明KVM 和KQEMU 間的關(guān)系,本文稱它為KVM 線程,而將創(chuàng)建客戶機(jī)的應(yīng)用程序KQEMU 稱為KQEMU 進(jìn)程。KQEMU 應(yīng)用程序在創(chuàng)建或者說(shuō)在加載一個(gè)Guest OS 后,就轉(zhuǎn)換為KVM 線程運(yùn)行。VCPU 的創(chuàng)建、初始化、運(yùn)行以及退出處理都在KVM 線程上下文中進(jìn)行,需要Kernel、User 和Guest 三種模式相互配合,其工作模型如圖2 所示:
圖2 KVM 工作模型
從圖2 可看出,KVM 線程以ioctl 的方式與KVM內(nèi)核模塊間進(jìn)行交互,指示KVM 內(nèi)核模塊進(jìn)行VCPU的創(chuàng)建和初始化等操作,而KVM 內(nèi)核模塊與客戶機(jī)之間通過(guò)VM Exit 和VM entry 操作進(jìn)行切換。初始化工作完成之后,KVM 線程以ioctl 的方式向KVM 內(nèi)核模塊發(fā)出運(yùn)行VCPU 的指示,后者執(zhí)行虛擬機(jī)進(jìn)入操作(VM entry),將處理器由Kernel 模式切換到Guest 模式,轉(zhuǎn)而運(yùn)行客戶機(jī)。但此時(shí)仍處于KVM 線程上下文中,且正在執(zhí)行ioctl 系統(tǒng)調(diào)用的kernel 模式處理程序。
客戶機(jī)在運(yùn)行過(guò)程中,如發(fā)生異;蛲獠恐袛嗟仁录驁(zhí)行I/O 操作,可能導(dǎo)致虛擬機(jī)退出操作(VMexit),將處理器狀態(tài)由Guest 模式切換回Kernel 模式。KVM內(nèi)核模塊檢查發(fā)生VM exit 的原因,如果VM exit由I/O 操作導(dǎo)致,則執(zhí)行系統(tǒng)調(diào)用返回操作,將I/O操作交給處于User 模式的KQEMU 進(jìn)程來(lái)處理,這時(shí)KQEMU會(huì)創(chuàng)建一個(gè)新的KQEMU線程來(lái)完成這些I/O處理,之后再次執(zhí)行ioctl,指示KVM 將處理器切換到Guest 模式,恢復(fù)客戶機(jī)的運(yùn)行;如果VM exit 由其它原因?qū)е,則由KVM 內(nèi)核模塊負(fù)責(zé)處理,并在處理后切換處理器到Guest 模式,恢復(fù)客戶機(jī)的運(yùn)行。
由以上分析可知,KVM 虛擬化技術(shù)中物理CPU核的隔離實(shí)現(xiàn),與KQEMU 應(yīng)用程序、KVM 線程、異步IO 事件處理這三方面有著密切的聯(lián)系。
3 虛擬機(jī)進(jìn)程隔離實(shí)現(xiàn)
3.1 隔離方案設(shè)計(jì)
在KVM 虛擬機(jī)運(yùn)行的過(guò)程中,與虛擬機(jī)處理器緊密相關(guān)的重要數(shù)據(jù)結(jié)構(gòu)VMCS保存在內(nèi)存中,包含了虛擬CPU 的相關(guān)寄存器的內(nèi)容和虛擬CPU 相關(guān)的控制信息,每個(gè)VMCS對(duì)應(yīng)一個(gè)虛擬CPU。但VMCS具有“遷移性”,使用時(shí)需要與物理CPU 綁定。例如,某個(gè)VMCS 先和物理CPU0 綁定,并在某個(gè)時(shí)刻解除綁定關(guān)系,下一個(gè)時(shí)刻可能會(huì)重新綁定到物理CPU1上。在任意給定時(shí)刻,VMCS 與物理CPU 是一對(duì)一的綁定關(guān)系,即一個(gè)VMCS 只能與一個(gè)物理CPU 綁定。
因此,多核條件下要實(shí)現(xiàn)Guest OS 在一個(gè)虛擬的單核平臺(tái)上運(yùn)行,就需要考慮KQEMU 應(yīng)用程序、KVM 線程、異步IO 事件處理與CPU 的綁定關(guān)系。利用CPU 的親和性(Affinity),通過(guò)設(shè)置這三方面的Affinity 屬性,可以將Guest OS 進(jìn)程綁定到指定的核上運(yùn)行,從而實(shí)現(xiàn)虛擬的單核平臺(tái)。例如,在創(chuàng)建虛擬機(jī)時(shí)將兩個(gè)Guest OS 進(jìn)程綁定到指定的CPU 核上,使其在整個(gè)運(yùn)行期間不發(fā)生遷移,如圖3 所示:
圖3 客戶操作系統(tǒng)與CPU 核的綁定
根據(jù)KVM 原理和機(jī)制的分析,可以通過(guò)兩個(gè)方案實(shí)現(xiàn)綁定操作:
方案一:直接通過(guò)內(nèi)核函數(shù)設(shè)置Guest OS 進(jìn)程的屬性,實(shí)現(xiàn)Guest OS 保持運(yùn)行在指定的核上。通過(guò)編寫(xiě)腳本文件,使創(chuàng)建虛擬機(jī)和綁定兩項(xiàng)操作自動(dòng)完成。
方案二:修改、優(yōu)化KQEMU 源代碼,生成特定的KVM 虛擬機(jī)。在創(chuàng)建客戶機(jī)的時(shí)候?qū)崿F(xiàn)綁定,使客戶機(jī)只能在指定核上的運(yùn)行,不發(fā)生遷移。
從兩個(gè)方案的設(shè)計(jì)可知,方案一的主要是從KQEMU應(yīng)用程序的應(yīng)用出發(fā)的,它的實(shí)現(xiàn)必然要用到文件的讀寫(xiě)和腳本的綁定,以及虛擬機(jī)管理器啟動(dòng)腳本的修改。方案二是基于Qemu 源代碼的修改,綁定時(shí)機(jī)明顯早于方案一,實(shí)現(xiàn)過(guò)程也更簡(jiǎn)單明了。除此之外,方案一從理論上來(lái)說(shuō),對(duì)有異步IO 時(shí)才產(chǎn)生的aio 線程的綁定可能出現(xiàn)問(wèn)題,所以本文最終選擇方案二。
3.2 處理器隔離的實(shí)現(xiàn)方法
Linux 的線程在核內(nèi)是以輕量級(jí)進(jìn)程的形式存在的,而實(shí)現(xiàn)是在核外。它擁有獨(dú)立的進(jìn)程表項(xiàng),其創(chuàng)建、刪除等操作都是在核外POSIX thread 庫(kù)中進(jìn)行。與fork() 調(diào)用創(chuàng)建一個(gè)進(jìn)程的方法不同,pthread_create()創(chuàng)建的線程并不具備與主線程同樣的執(zhí)行序列,而是使其運(yùn)行start_routine()函數(shù)。因此,用fork 創(chuàng)建的父子進(jìn)程之間的Affinity 具有繼承性,而調(diào)用pthread_create()創(chuàng)建的父子進(jìn)程之間則沒(méi)有這種繼承性,KQEMU 和KVM 之間則是后者的情況。
因此,僅通過(guò)設(shè)置KQEMU 的Affinity 屬性不能實(shí)現(xiàn)KVM 虛擬機(jī)處理器的隔離。需分為兩部分處理:
①?gòu)膯?dòng)QEMU 的命令獲取cpuid 參數(shù)。這需要對(duì)KQEMU 源代碼進(jìn)行修改,增加-cpuid 的命令選項(xiàng),完成對(duì)參數(shù)的解析以及相關(guān)的綁定操作。主要涉及KQEMUOption、KQEMU_options 等幾個(gè)選項(xiàng)變量。
②根據(jù)解析獲得的cpuid 參數(shù),對(duì)KQEMU 應(yīng)用進(jìn)程、KVM 線程、異步IO 事件處理線程運(yùn)用Linux 內(nèi)核的Affinity 機(jī)制進(jìn)行綁定,實(shí)現(xiàn)對(duì)處理器的隔離。圖4 是以雙核處理器為例實(shí)現(xiàn)KVM虛擬機(jī)綁定的主要過(guò)程。
圖4 KVM 虛擬機(jī)進(jìn)程綁定實(shí)現(xiàn)過(guò)程
4 實(shí)驗(yàn)結(jié)果與分析
由設(shè)計(jì)思路的分析可知,對(duì)方案二實(shí)現(xiàn)方法需要驗(yàn)證的是客戶機(jī)的創(chuàng)建、客戶機(jī)的運(yùn)行,以及客戶機(jī)的異步IO 事件處理。本實(shí)驗(yàn)中使用的測(cè)試平臺(tái)是:處理器是Pentium(R) Dual-Core CPU E5300 2.60GHz,內(nèi)存為DDR2-800 2G , 操作系統(tǒng)內(nèi)核版本是Linux-2.6.33.2 。GuestOS 運(yùn)行測(cè)試程序是計(jì)算Fibonacci 前35 項(xiàng)和,每計(jì)算一次休眠15 毫秒。
執(zhí)行命令qemu-system-x86_64 Guestos.img –m512–cpuid 1,在啟動(dòng)Guest OS 時(shí)指定創(chuàng)建Guest OS進(jìn)程的處理器參數(shù)cpuid,使創(chuàng)建客戶機(jī)的進(jìn)程在指定的核1 運(yùn)行。用top 命令的p 和H 參數(shù),觀察KVM虛擬機(jī)運(yùn)行時(shí)的進(jìn)程號(hào)和線程號(hào)。
t1 時(shí)刻(19:33:34),KQEMU 進(jìn)程號(hào)為3905,KVM線程號(hào)為3906,異步IO 事件處理線程號(hào)為3910,如圖5 所示:
圖5 t1 時(shí)刻KVM 虛擬機(jī)進(jìn)程運(yùn)行狀態(tài)
t2 時(shí)刻(20:43:20),KQEMU 進(jìn)程號(hào)為3905,KVM線程號(hào)為3906,異步IO 事件處理線程號(hào)為4212,如圖6 所示。此時(shí)圖4 中線程號(hào)為3910 的aio 線程消失,動(dòng)態(tài)產(chǎn)生aio 線程4212。
圖6 t2 時(shí)刻KVM 虛擬機(jī)進(jìn)程運(yùn)行狀態(tài)
根據(jù)Linux 內(nèi)核的PID 命名規(guī)則可知,PID 逐漸遞增,aio 線程的產(chǎn)生是一個(gè)動(dòng)態(tài)過(guò)程,根據(jù)Guest OS的需要而產(chǎn)生。從而進(jìn)一步證實(shí),如果用采用方案一,則難以實(shí)現(xiàn)aio線程的綁定。
經(jīng)過(guò)長(zhǎng)時(shí)間的實(shí)驗(yàn)觀察,雖然運(yùn)行Guest OS 時(shí)CPU 核1 的利用率達(dá)到94.7%左右,KVM 虛擬機(jī)始終保持在指定的核1 運(yùn)行,即使核0 十分空閑,仍不會(huì)發(fā)生遷移。可以通過(guò)taskset 命令查看這三個(gè)進(jìn)程的Affinity 值,得到進(jìn)一步的驗(yàn)證,如圖7 所示。圖中3905 , 3906 , 4212 進(jìn)程的Affinity 值為2 ( 即0x00000010),表示相應(yīng)進(jìn)程或線程運(yùn)行在核1 上。
圖7 用taskset 命令查看虛擬機(jī)進(jìn)程的Affinity 值
5 結(jié)論
本文通過(guò)對(duì)KVM 虛擬機(jī)的綁定,實(shí)現(xiàn)了KVM 虛擬機(jī)處理器核之間的隔離,使KVM 虛擬機(jī)在指定的物理CPU 核上運(yùn)行,不發(fā)生核間的遷移,從而達(dá)到物理CPU 資源的指定使用。當(dāng)運(yùn)行多個(gè)Guest OS 時(shí),只需在運(yùn)行時(shí)指定CPU 參數(shù),即可讓各個(gè)Guest OS始終運(yùn)行在指定的核上,進(jìn)而能夠充分有效地利用計(jì)算機(jī)硬件資源。
核心關(guān)注:拓步ERP系統(tǒng)平臺(tái)是覆蓋了眾多的業(yè)務(wù)領(lǐng)域、行業(yè)應(yīng)用,蘊(yùn)涵了豐富的ERP管理思想,集成了ERP軟件業(yè)務(wù)管理理念,功能涉及供應(yīng)鏈、成本、制造、CRM、HR等眾多業(yè)務(wù)領(lǐng)域的管理,全面涵蓋了企業(yè)關(guān)注ERP管理系統(tǒng)的核心領(lǐng)域,是眾多中小企業(yè)信息化建設(shè)首選的ERP管理軟件信賴品牌。
轉(zhuǎn)載請(qǐng)注明出處:拓步ERP資訊網(wǎng)http://www.ezxoed.cn/
本文標(biāo)題:KVM虛擬化技術(shù)中處理器隔離的實(shí)現(xiàn)
本文網(wǎng)址:http://www.ezxoed.cn/html/support/1112158584.html