快捷搜索:  汽车  科技

vai系统设计(virtio设备和驱动概述)

vai系统设计(virtio设备和驱动概述)设备状态字段是设备和驱动程序用于执行其初始化的位序列。我们可以将其想象为控制台上的交通信号灯,设置每个零件并清除指示其状态的每个位。现在,我们将为每个部分提供更多详细信息,以及设备和驱动程序如何开始使用它们进行通信。virtio设备是公开virtio接口以供软件管理和交换信息的设备。可以使用PCI,内存映射I/O(仅将设备暴露在内存区域中)和S/390通道I/O暴露给仿真环境。通信的一部分需要委托给这些,例如设备发现。它的主要任务是将信号从虚拟环境之外的格式(VM,容器等)转换为需要通过virtio数据层交换的格式,反之亦然。该信号可以是真实的(例如,来自NIC的电或光),也可以是虚拟的(例如,主机从网络数据包中获得的表示)。virtio接口包含以下必填部分(virtio1.1 spec):

打包的virtqueue(补充了拆分的virtqueue)已在virtio 1.1规范中合并,并已在模拟设备(qemu,virtio_net,dpdk)和物理设备中成功实现。

我们将从对virtio设备,驱动程序及其数据层交互的概述开始。然后,我们将继续解释拆分式virtqueue环布局的详细信息。接下来是打包的virtqueue与拆分式virtqueue方法相比所带来的优点的概述。

Virtio设备和驱动程序概述

本节简要介绍了virtio设备,virtio驱动程序,可以使用的不同体系结构和不同组件的示例。

Virtio设备

virtio设备是公开virtio接口以供软件管理和交换信息的设备。可以使用PCI,内存映射I/O(仅将设备暴露在内存区域中)和S/390通道I/O暴露给仿真环境。通信的一部分需要委托给这些,例如设备发现。

它的主要任务是将信号从虚拟环境之外的格式(VM,容器等)转换为需要通过virtio数据层交换的格式,反之亦然。该信号可以是真实的(例如,来自NIC的电或光),也可以是虚拟的(例如,主机从网络数据包中获得的表示)。

virtio接口包含以下必填部分(virtio1.1 spec):

  • 设备状态字段
  • 功能位
  • 通知事项
  • 一种或多种virtqueues

现在,我们将为每个部分提供更多详细信息,以及设备和驱动程序如何开始使用它们进行通信。

设备状态字段

设备状态字段是设备和驱动程序用于执行其初始化的位序列。我们可以将其想象为控制台上的交通信号灯,设置每个零件并清除指示其状态的每个位。

guest或驱动程序在设备状态字段中设置ACKNOWLEDGE(0x1)位表示已确认该设备,DRIVER(0x2)表示正在进行的初始化。此后,它将使用功能位开始功能协商(稍后会详细介绍),DRIVER_OK(0x4)和FEATURES_OK(0x8)设置为确认功能,以便可以开始通信。如果设备要指示致命故障,则可以将DEVICE_NEEDS_RESET(0x40)置1,驱动程序也可以对FAILED(0x80)进行设置。

该设备使用特定于传输的方法(例如PCI扫描或知道MMIO的地址)传达这些位的位置。

功能位

设备的功能位用于传达其支持的功能,并与驱动程序就将使用哪些功能达成一致。这些可以是设备通用的或特定于设备的。作为第一种情况的示例,一位可以确认设备是否支持SR-IOV或可以使用哪种存储模式。第二种情况的一个例子是它可以执行的不同卸载,例如校验和或分散聚集(如果设备是网络接口)。

在上一节中介绍的设备初始化之后,前者读取设备提供的功能位,然后将其可以处理的子集发送回去。如果他们同意,驱动程序将分配并告知设备虚拟状态以及所需的所有其他配置。

通知

设备和驱动程序必须使用通知来通知他们有信息可以进行通信。尽管在标准中指定了它们的语义,但是它们的实现是特定于传输的,例如PCI中断或写入特定的内存位置。设备和驱动程序需要公开至少一种通知方法。我们将在以后的部分中对此进行扩展。

一种或多种virtqueues:通讯工具

一个virtqueue只是host使用的guest缓冲队列(读取或写入它们,然后返回给guest)。当前实现的virtqueue内存布局是一个圆环,因此通常称为virtring或vring。

Virtio驱动程序

virtio驱动程序是虚拟环境中的软件部分,它使用virtio规范的相关部分与virtio设备进行通讯。

一般来说,其virtio控制层任务是:

  • 寻找设备
  • 在guest中分配共享内存以进行通信

使用Virtio设备中的协议启动它。

设备和驱动程序的交互

在本节中,我们将在三种不同的体系结构中定位每个virtio网络元素(设备,驱动程序以及通信方式),以提供一个共同的框架来开始解释virtio数据层并展示其适应性。我们已经在过去的文章中介绍了这些元素,因此,如果您是virtio-net系列读者,则可以跳过本节。另一方面,如果您还没有阅读它们,则可以将它们用作参考,以更好地理解这一部分。

在virtio-networking和vhost-net介绍中,我们展示了qemu创建模拟网络设备并将其提供给guest virtio-net驱动程序的环境。在这种环境中,驱动程序通知将从对guest公开的任何方法(通常是PCI)路由到KVM中断,从而中断guest的处理器并将控制权返回给host(vmexit)。同样,设备通知是host可以发送到KVM设备的特殊ioctl(vCPU IRQ)。QEMU可以使用共享内存访问virtqueue信息。

注意,virtio环共享内存概念的含义:驱动程序和设备访问的内存在RAM中是同一页,它们不是遵循协议进行同步的两个不同区域。

vai系统设计(virtio设备和驱动概述)(1)

图1:Qemu仿真设备组件图

由于通知现在需要从guest(KVM)传输到QEMU,然后到内核以后者转发网络帧,因此我们可以在内核中生成一个线程,该线程可以访问guest的共享内存映射,然后让它处理virtio数据层。

在这种情况下,QEMU使用virtio数据层启动设备,然后将virtio设备状态转发到vhost-net,将数据层委托给它。在这种情况下,KVM将使用事件文件描述符(eventfd)来传达设备中断,并公开另一个事件文件描述符以接收CPU中断。guest不需要知道此更改,它将像以前的情况一样进行操作。

另外,为了提高性能,我们创建了一个内核内部的virtio-net设备(称为vhost-net),将数据层直接卸载到发生数据包转发的内核:

vai系统设计(virtio设备和驱动概述)(2)

图2:Virtio-net组件图

稍后,我们将virtio设备从内核移到了host中的用户空间进程,该主机可以运行像DPDK这样的数据包转发框架。设置所有这些的协议称为virtio-user。

vai系统设计(virtio设备和驱动概述)(3)

图3:Virtio用户组件图

它甚至允许guest在guest的用户区中运行virtio驱动程序,而不是内核!在这种情况下,virtio名称会驱动正在管理内存和virtqueue的进程,而不是在guest虚拟机中运行的内核代码。

vai系统设计(virtio设备和驱动概述)(4)

图4:Virtio-user和guest虚拟机中的userland驱动程序

最后,我们可以使用适当的硬件直接进行virtio设备直通。如果NIC支持virtio数据层,我们可以使用适当的硬件(IOMMU设备,能够在客户机和设备的内存地址之间进行转换)和软件(例如,VFIO linux驱动程序)将其直接暴露给客户机,以使主机能够直接将PCI设备的控制权交给guest)。该设备将典型的硬件信号用于通知基础结构,例如PCI和CPU中断(IRQ)。

如果硬件NIC希望采用这种方式,则最简单的方法是在vDPA之上构建其驱动程序。

vai系统设计(virtio设备和驱动概述)(5)

图5:Virtio硬件直通组件图

猜您喜欢: