官术网_书友最值得收藏!

2.2 QEMU線程模型

2.2.1 QEMU線程模型簡介

QEMU-KVM架構中,一個QEMU進程代表一個虛擬機。QEMU會有若干個線程,其中對于每個CPU會創建一個線程,還有其他的線程,如VNC線程、I/O線程、熱遷移線程,QEMU線程模型如圖2-12所示。

圖2-12 QEMU線程模型

傳統上,QEMU主事件循環所在的線程由于會不斷監聽各種I/O事件,所以被稱為I/O線程。現在的I/O線程通常是指塊設備層面的單獨用來處理I/O事件的線程。每一個CPU都會有一個線程,通常叫作VCPU線程,其主要的執行函數是kvm_cpu_exec,比如圖2-12中有3個VCPU線程。QEMU為了完成其他功能還會有一些輔助線程,如熱遷移時候的migration線程、支持遠程連接的VNC和SPICE線程等。

線程模型通常使用QEMU大鎖進行同步,獲取鎖的函數為qemu_mutex_lock_iothread,解鎖函數為qemu_mutex_unlock_iothread。實際上隨著演變,現在這兩個函數已經變成宏了。很多場合都需要BQL,比如os_host_main_loop_wait在有fd返回事件時,在進行事件處理之前需要調用qemu_mutex_lock_iothread獲取BQL;VCPU線程在退出到QEMU進行一些處理的時候也會獲取BQL。下面的代碼是main函數主循環中獲取BQL的過程。

2.2.2 QEMU線程介紹

1.VCPU線程

QEMU虛擬機的VCPU對應于宿主機上的一個線程,通常叫作VCPU線程。在x86_cpu_realizefn函數中進行CPU具現(CPU具現的概念會在2.4節中介紹)的時候會調用qemu_init_vcpu函數來創建VCPU線程。qemu_init_vcpu根據加速器的不同,會調用不同的函數來進行VCPU的創建,對于KVM加速器來說,這個函數是qemu_kvm_start_vcpu,該函數的代碼如下。

qemu_thread_create調用了pthread_create來創建VCPU線程。VCPU線程用來執行虛擬機的代碼,其線程函數是qemu_kvm_cpu_thread_fn。

2.VNC線程

在main函數中,會調用vnc_init_func對VNC模塊進行初始化,經過vnc_display_init->vnc_start_worker_thread的調用最終創建VNC線程,VNC線程用來與VNC客戶端進行交互。

3.I/O線程

設備模擬過程中可能會占用QEMU的大鎖,所以如果是用磁盤類設備進行讀寫,會導致占用該鎖較長時間。為了提高性能,會將這類操作單獨放到一個線程中去。QEMU抽象出了一個新的類型TYPE_IOTHREAD,可以用來進行I/O線程的創建。比如virtio塊設備在其對象實例化函數中添加了一個link屬性,其對應的連接對象為一個TYPE_IOTHREAD。

當進行數據面的讀寫時,就可以使用這個iothread進行。

當然,QEMU還會有其他線程,比如說熱遷移線程以及一些設備模擬自己創建的線程,這里就不一一介紹了。

如同Linux內核中的大鎖,BQL會對QEMU虛擬機的性能造成很大影響。早期的QEMU代碼在握有BQL時做的事情很多,QEMU多線程的主要動力是減少QEMU主線程的運行時間,QEMU在進行一些設備模擬的時候,VCPU線程會退出到QEMU,搶占QEMU大鎖,如果這個時候有其他線程占據大鎖,再做長時間的工作就會導致VCPU被掛起比較長的時間,所以將一些沒有必要占據QEMU大鎖的任務放到單獨線程進行處理就能夠增加VCPU的運行時間,這也是QEMU社區在多線程方向的努力方向,即盡量將任務從QEMU大鎖中拿出來。

主站蜘蛛池模板: 曲周县| 尤溪县| 修武县| 北碚区| 平泉县| 平和县| 星子县| 胶南市| 青州市| 宜丰县| 延津县| 湘潭市| 明水县| 黄大仙区| 泾源县| 开江县| 桑日县| 桃园县| 定南县| 乌审旗| 洱源县| 繁峙县| 连州市| 藁城市| 凉城县| 广汉市| 苗栗市| 玉环县| 嘉黎县| 铜山县| 汉川市| 南岸区| 沙雅县| 佛教| 高密市| 从化市| 江孜县| 隆昌县| 宁夏| 长海县| 政和县|