本文首发于个人公众号 Linux云计算网络(id: cloud_dev),专一于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」便可领取,欢迎你们关注,二维码文末能够扫。前端
vhost 是 virtio 的一种后端实现方案,在 virtio 简介中,咱们已经提到 virtio 是一种半虚拟化的实现方案,须要虚拟机端和主机端都提供驱动才能完成通讯,一般,virtio 主机端的驱动是实如今用户空间的 qemu 中,而 vhost 是实如今内核中,是内核的一个模块 vhost-net.ko。为何要实如今内核中,有什么好处呢,请接着往下看。编程
在 virtio 的机制中,guest 与 用户空间的 Hypervisor 通讯,会形成屡次的数据拷贝和 CPU 特权级的上下文切换。例如 guest 发包给外部网络,首先,guest 须要切换到 host kernel,而后 host kernel 会切换到 qemu 来处理 guest 的请求, Hypervisor 经过系统调用将数据包发送到外部网络后,会切换回 host kernel , 最后再切换回 guest。这样漫长的路径无疑会带来性能上的损失。后端
vhost 正是在这样的背景下提出的一种改善方案,它是位于 host kernel 的一个模块,用于和 guest 直接通讯,数据交换直接在 guest 和 host kernel 之间经过 virtqueue 来进行,qemu 不参与通讯,但也没有彻底退出舞台,它还要负责一些控制层面的事情,好比和 KVM 之间的控制指令的下发等。网络
下图左半部分是 vhost 负责将数据发往外部网络的过程, 右半部分是 vhost 大概的数据交互流程图。其中,qemu 仍是须要负责 virtio 设备的适配模拟,负责用户空间某些管理控制事件的处理,而 vhost 实现较为纯净,以一个独立的模块完成 guest 和 host kernel 的数据交换过程。工具
vhost 与 virtio 前端的通讯主要采用一种事件驱动 eventfd 的机制来实现,guest 通知 vhost 的事件要借助 kvm.ko 模块来完成,vhost 初始化期间,会启动一个工做线程 work 来监听 eventfd,一旦 guest 发出对 vhost 的 kick event,kvm.ko 触发 ioeventfd 通知到 vhost,vhost 经过 virtqueue 的 avail ring 获取数据,并设置 used ring。一样,从 vhost 工做线程向 guest 通讯时,也采用一样的机制,只不过这种状况发的是一个回调的 call envent,kvm.ko 触发 irqfd 通知 guest。性能
vhost 与 kvm 的事件通讯经过 eventfd 机制来实现,主要包括两个方向的 event,一个是 guest 到 vhost 方向的 kick event,经过 ioeventfd 实现;另外一个是 vhost 到 guest 方向的 call event,经过 irqfd 实现。云计算
代码分析整个通讯的流程:
http://royluo.org/2014/08/22/vhost/线程
个人公众号 「Linux云计算网络」(id: cloud_dev) ,号内有 10T 书籍和视频资源,后台回复 「1024」 便可领取,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎你们关注。3d