一、前言
在文章《DPDK系列之十五:Virtio技術分析之一,virtio基礎架構》中,可以看到傳統的virtio機制需要qemu來模拟使用者态IO,是以虛拟機内部的IO請求從産生、發送到qemu、再到主控端網絡,需要多次跨越核心進行拷貝和處理器運作登記切換,影響性能。是以引入了vhost方案,将virtio的後端放到核心之中,這樣virtio後端與主控端上對于的tap裝置的資料收發可以直接在核心進行,提高了效率。
classic virtio vhost
轉載自https://blog.csdn.net/cloudvtech
二、vhost工作機制
vhost使用核心驅動的方式将virtio的後端直接放入核心,這樣虛拟機和宿主的溝通過程中就不會再向主控端的userspace進行切換和資料拷貝。
2.1 qemu端的處理
在啟動虛拟機的時候,指定-netdev tap時加入vhost=on,就會在qemu端enable vhost機制。tap在建立的時候,如果發現vhost=on,則會調用相應的初始化函數,通過open(“/dev/vhost-net”, O_RDWR)打開了vhost driver;并通過ioctl(vhost_fd)進行了一系列的初始化,并設定kick fd和call fd。
2.2 核心中的處理
vhost在核心中是以miscdevice的形式注冊的,在初始化過程中,vhost driver建立了一個名為“vhost-$pid”核心線程,$pid為Qemu的PID。這個核心線程被稱為“vhost worker thread”,用于處理virtio的IO事件。
但是由于vhost并沒有模拟一個完整的PCI擴充卡。它内部隻涉及了virtqueue的操作,而virtio裝置的适配模拟仍然由Qemu來負責。是以vhost還依賴于使用者空間qemu的管理平面進行配置和處理,而自身完成位于Host Kernel層的資料面處理。
vhost與kvm的事件通信通過eventfd機制來實作,虛拟機到vhost方向的kick event,通過ioeventfd承載;另一個是vhost到虛拟機方向的call event,通過irqfd承載。
2.3 虛拟機内部的處理
enable vhost的virtio裝置的初始化流程和普通virtio基本上一緻,使之最後會将初始化好的vring的資訊通過ioctl發送給vhost,這樣virtio的vring區域就被主控端核心中的vhost所感覺和共享。
虛拟機資料的發送和傳統的virtio類似,都是通過操作基于共享記憶體的vring實作的,隻是在資料進入核心之後,vhost會直接将資料發送給tap裝置,不用再進入userspace。
轉載自https://blog.csdn.net/cloudvtech
三、vhost-user的工作機制
vhost借助核心驅動機制将virtio的後端從使用者态的qemu程序移到了核心态,進而減少跨越核心的切換和資料拷貝;而vhost-user則借助Linux的UIO機制進一步再将這個virtio的後端移到使用者态,一些實作了vhost backend的交換機(如OVS-DPDK的type=dpdkvhostuser的端口)直接在使用者态從vhost共享的虛拟機網卡緩存區vring中把網絡資料進行讀取,并發送到實體網卡上,進而大大提升了性能:
主控端端實作使用者态的DPDK host-user,虛拟機端采用virtio DPDK PMD,可以實作基于DPDK的高速資料面。DPDK的vhost-user包含的基本功能有:
- virtio網絡裝置管理和後端的實作
- 共享記憶體的映射、虛拟隊列資料的處理
- 接受kick event和發送call event
- 虛拟隊列和實際的實體網卡間的資料收發
轉載自https://blog.csdn.net/cloudvtech