VirtIO实现原理之数据结构与数据传输演示(1)

132 篇文章 41 订阅 yen49.90 yen99.00

本文内容参考:

VirtIO实现原理——vring数据结构-CSDN博客

VirtIO实现原理——数据传输演示-CSDN博客

特此致谢!

序言

本系列文章是笔者在看了网名为“享乐主”的VirtIO系列文章后决心要写的。这位博主的“VirtIO专栏”中博文的内容从技术层面来讲写得非常好,既有广度又有深度。但是如果论文笔、行文方式以及易理解程度,就还有比较大的提升空间了。

ac86e5988a9740f9974d33b4c568300c.png

笔者就用本系列文章,以“享乐主”的“VirtIO”专栏文章为蓝本以及主线脉络,以自己的理解和行文方式撰写这一系列文章。一方面,可以算作对原系列文章的“注”(当然,不仅仅是注);另一方面,也会结合笔者自己的理解、笔者既有文章中的知识点以及QEMU/KVM源码进行补充和拓展。本系列文章将收录到笔者的“QEMU/KVM”专栏中。

在开始正式文章之前,再次表达对“享乐主”的谢意!

一、数据结构总览

1. virtqueue规范

先来研读一下《Virtual I/O Device (VIRTIO) Version 1.3》规范的“2.6 Virtqueues”一节中的内容。

7208ea0225284ca5a920d5d290c4e94c.png

1e74e93eafd046a0b388e4b2d371386f.png

2.6 Virtqueue

在virtio设备上进行批量数据传输的机制被自命为virtqueue。每个设备可以有零个或多个virtqueues。例如,最简单的网络设备有一个用于传输的virtqueue和一个用于接收的virtqueue。

一个virtio设备最多可以有65536个virtqueue。每个virtqueue都由virtqueue索引标识。virtqueue的值在0到65535的范围内。

驱动程序通过向队列添加可用缓冲区(例如,向virtqueue添加描述请求的缓冲区),以及可选地触发驱动程序事件(例如,向设备发送可用缓冲区通知),使请求对设备可用。

设备执行请求,并在完成时将已使用的缓冲区添加到队列中(例如,通过将缓冲区标记为已使用来让驱动程序知道)。然后,设备可以触发设备事件(例如,向驱动程序发送已使用缓冲区通知)。

设备报告其使用的每个缓冲区已写入内存的字节数。这被称为“使用长度”。设备通常不需要按照驱动程序提供缓冲区的顺序使用缓冲区。

一些设备总是按照它们可用的顺序使用描述符。这些设备可以提供VIRTIO_F_IN_ORDER功能。如果协商一致,这些知识可能会允许优化或简化驱动程序和/或设备代码。

每个virtqueue最多可由3个部分组成

  • 描述符区域(Descriptor Area)

用于描述缓冲区。

  • 驱动区域(Driver Area)

驱动向设备提供的额外数据。

  • 设备区域(Device Area)

设备向驱动提供的额外数据。

注:

请注意,本规范的先前版本对这些部件使用了不同的名称(以下为2.7):

  • 描述符表(Descriptor Table)

用于描述符区域。

  • 可用环(Available Ring)

用于驱动区域。

  • 已用环(Used Ring)

用于设备区域。

下一回对virtqueque这3个组成部分进行详细解析。