vhost-user

virtio,vhost,vhost-user 是基于场景和性能而提出的三种 guest 和 host 之间的通信方案,三种方案,各有优劣。

在 vhost 的方案中,由于 vhost 实现在内核中,guest 与 vhost 的通信,相较于原生的 virtio 方式性能上有了一定程度的提升,从 guest 到 kvm.ko 的交互只有一次用户态的切换以及数据拷贝。这个方案对于不同 host 之间的通信,或者 guest 到 host nic 之间的通信是比较好的,但是对于某些用户态进程间的通信,比如数据面的通信方案,openvswitch 和与之类似的 SDN 的解决方案,guest 需要和 host 用户态的 vswitch 进行数据交换,如果采用 vhost 的方案,guest 和 host 之间又存在多次的上下文切换和数据拷贝,为了避免这种情况,业界就想出将 vhost 从内核态移到用户态。这就是 vhost-user 的实现。

vhost-user 和 vhost 的实现原理是一样,都是采用 vring 完成共享内存,eventfd 机制完成事件通知。不同在于 vhost 实现在内核中,而 vhost-user 实现在用户空间中,用于用户空间中两个进程之间的通信,其采用共享内存的通信方式。
这里写图片描述
vhost-user是vhost-kernel又回到用户空间的实现,其基本思想和vhost-kernel很类似,不过之前在内核的部分现在有另外一个用户进程代替,可能是snapp或者dpdk等。虽然和vhost-kernel实现的目标一致,但是具体的实现方式却有所不同。vhost-user下,UNIX本地socket代替了之前kernel模式下的设备文件进行进程间的通信(qemu和vhost-user app),而通过mmap的方式把ram映射到vhost-user app的进程空间实现内存的共享。其他的部分和vhost-kernel原理基本一致。这种情况下一般qemu作为client,而vhost-user app作为server如DPDK。而本文对于vhost-user server端的分析主要也是基于DPDK源码。本文主要分析涉及到的三个重要机制:qemu和vhost-user app的消息传递,guest memory和vhost-user app的共享,guest和vhost-user app的通知机制。

消息机制

当使用vhost-user时,需要在系统中创建一个unix domain socket server,用来处理qemu发送给host的消息。
如果有新的socket连接,说明guest创建了新的virtio-net设备,vhost驱动会为之创建一个vhost设备,之后qemu就可以通过socket和vhost进行通信了;当socket关闭,vhost就会销毁对应的设备。

一旦连接建立了,DPDK vhost-user将会启动接收并处理来自QEMU的vhost消息。
对于文件描述符的消息,文件描述符可以直接在vhost进程里,当它已经通过 Unix domain socket安装了。
支持如下的vhost消息:

VHOST_SET_MEM_TABLE
VHOST_SET_VRING_KICK
VHOST_SET_VRING_CALL
VHOST_SET_LOG_FD
VHOST_SET_VRING_ERR

对于VHOST_SET_MEM_TABLE消息,QEMU会发送每一个内存区域的信息并且它的文件描述符在这个消息的辅助数据里。这个文件描述就是用来映射这块内存区域的。

VHOST_SET_VRING_KICK用来作为信号将vhost设备放入到数据平面,VHOST_GET_VRING_BASE作为信号去数据平面删除vhost设备。
当socket连接关闭时,vhost会删除这个设备。

猜你喜欢

转载自blog.csdn.net/qq_15437629/article/details/81226901