2017-11-15
今天閑着沒有突然想了想VCPU線程調度的問題,具體描述如下:
當代表VCPU的線程獲得控制權后,首先會通過KVM接口進入到內核,從內核進入到非根模式,那么此時站在全局調度器的點上,這並不算做線程的時間,這種情況下調度器還能正常調度VCPU線程嗎?
通過查看intel手冊,分析相關時鍾中斷的源代碼,目前理解如下:
基本知識:
CPU的VMX模式分為root模式和non root模式,二者的0-3環是正交的,即在root模式下有ring0~ring3,在non root模式下也有ring 0到ring3,一個VCPU線程得到運行,通過KVM接口進入到內核,最終需要從root模式進入到non root模式,進入non root模式后就是虛擬機運行的階段了。虛擬機有自己的內核層和用戶層,即ring0-ring3。
按照當前Linux下的CFS調度器為例,基於虛擬運行時間來調度進程,而虛擬運行時間的統計本質上還是基於時鍾中斷。時鍾中斷處理程序中會分析當前CPU處於ring0 還是ring3(不區分root和non root),繼而更新進程時間統計量。之前聽人說進程在內核中的時間是不算做調度參考時間的,但是根據代碼來看,時鍾中斷時不管是處理用戶態還是內核態,最終都會增加對應進程的虛擬運行時間,這點如有仁兄明白還請告知。而在中斷會返回的時候,我們知道在搶占內核下,會增加一個調度時機,此時如果有更加緊迫的進程需要執行,則進行內核搶占。如果返回用戶空間,則正常進行調度的檢查。
回到開始我們提出的問題,假如一個虛擬機正在運行,此時時鍾中斷到來,那么CPU 在保存現場后,繼而去執行中斷處理程序,其中就會統計當前進程(必然是VCPU線程)的時間信息,並會更新VCPU線程的虛擬運行時間,如果運行時間到了則設置重調度位,處理完成后返回。如果之前虛擬機位於內核模式(non root 下的內核模式)且支持內核搶占,則會觸發調度器進行調度;如果虛擬機位於用戶模式,則會直接觸發調度。所以從這里看,HOST上調度器的運行和VMX模式並沒有本質聯系。而虛擬機內部進程的調度就比較容易理解了,和傳統進程調度沒有區別,雖然INTEL手冊嚴格規定了non root模式下不允許任務切換嗎,但是其實針對使用TSS來說的,而現實情況下,不管是windows還是Linux 都沒有使用TSS做任務切換,故實際上虛擬機內部進程切換還是在non root 模式下進行的(至少目前我是這么認為的)
以馬內利
參考:
intel 手冊
Linux內核源碼