设备虚拟化

引子

几年前,就已经听说有网卡厂商想做基于virtio规范的设备了,这样就可以避免在内核中上传设备驱动。
那时候在想设备怎么构建竞争力或者在哪一层隐藏设备的复杂性呢?
最近无意中看到vdpa的概念,才发现这恰恰就是我想要找的答案,于是就忍不住想整理总结下。

设备驱动和虚拟化相关技术

一个新设备硬件出来后,为了在在linux kernel下使用它,我们一般都是在linux kerneldrivers目录下,基于内核框架为该
设备新写一个驱动程序。另外,用户态的业务程序也可能会为了适配该设备做相应的修改。
这样就带来一个问题,为了在正式发行版中使用该设备,我们不得不把设备驱动合入到内核主线中,或者针对不同的操作系统版本,
维护一系列驱动包,兼容和维护性的工作量很大。
此外,在云上,云厂商很难兼容不同厂商的硬件,而且云厂商为了构建自己的竞争力,也会下场做设备,比如亚马逊和阿里等。
于是乎,virtio设备规范就出来了,这个技术带来了很好的兼容性,但是牺牲了部分性能。
所以呢,vdpavirtio data patch acceleration的概念就出来了。

演进的历史roadmap如下,转自字节跳动。

device virtulization roadmap

从上图中,其实也看出VDPA是从最开始的vhost datapath acc演变成virtio datapath acc的。
在VM中对用户呈现的都是标准的virtio设备(virtio-net/blk),同时把数据面和控制面解耦:

  • 数据面:直接使用内核原生的virtio-net/blk驱动,通过virtqueues组成一个ring buffer,传递数据buffer描述符
  • 控制面:使用各个厂家的驱动来管理数据面的virtqueues,做特性协商和共享内存的配置,对于软件可见的设备特性均已在”virtio规范中”覆盖,比如一个网卡:

    • generic device state (status, feature bits, num_queues)
    • per-virtqueue state (base, addr, size)
    • feature state present in config space (mac, mtu, link status, …)
    • feature state invisible in config space (mac_table, vlan, rx, rss, …)
    • device specific state not backed by feature (virtio-blk/scsi in-flight request)

vhost datapath acc

基于vhost的方案如下,后面为了避免陷入内核,对标vhost-user增加了一个类似vfio relay的方案。

vhost dpa overview2

vdpa整体架构

vdpa整体架构如下,数据面上,设备厂商遵循virtio-spec;控制面上由厂商指定,基于netlink机制打通用户态和内核态。

vdpa overview2

vdpa overview

其中,vdpa bus driver用于把vdpa device透传到不同的内核子系统,比如virtio或者vhost等。
vhost-vdpa基本用于虚拟机场景,虚拟机内使用virtio设备。
virtio-vdpa基本用于裸机或者容器场景,host内直接使用virtio设备驱动。

参考

知道是不会有人点的,但万一有人呢:)