本文内容参考:
特此致谢!
序言
本系列文章是笔者在看了网名为“享乐主”的VirtIO系列文章后决心要写的。这位博主的“VirtIO专栏”中博文的内容从技术层面来讲写得非常好,既有广度又有深度。但是如果论文笔、行文方式以及易理解程度,就还有比较大的提升空间了。
笔者就用本系列文章,以“享乐主”的“VirtIO”专栏文章为蓝本以及主线脉络,以自己的理解和行文方式撰写这一系列文章。一方面,可以算作对原系列文章的“注”(当然,不仅仅是注);另一方面,也会结合笔者自己的理解、笔者既有文章中的知识点以及QEMU/KVM源码进行补充和拓展。本系列文章将收录到笔者的“QEMU/KVM”专栏中。
在开始正式文章之前,再次表达对“享乐主”的谢意!
一、数据结构总览
1. virtqueue规范
先来研读一下《Virtual I/O Device (VIRTIO) Version 1.3》规范的“2.6 Virtqueues”一节中的内容。
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个组成部分进行详细解析。