Expand description
Split virtqueue implementation for virtio devices.
Implements the split virtqueue data structure used by legacy and transitional virtio devices, as specified in the virtio specification, section 2.7.
A virtqueue consists of three physically contiguous regions:
- Descriptor table – array of
VirtqDescentries describing data buffers (16 bytes each) - Available ring (
VirtqAvail) – driver-to-device: ring of descriptor chain heads - Used ring (
VirtqUsed) – device-to-driver: ring of completed descriptor chain heads
Memory layout follows the virtio specification: descriptors at the base, available ring immediately after, used ring page-aligned after that.
§Thread Safety
VirtQueue is not internally synchronized. It implements Send and
Sync only because it is always held behind a Mutex in the virtio-blk
driver (VIRTIO_BLK: OnceLock<Mutex<VirtioBlkDevice>>). Callers MUST NOT
access a VirtQueue from multiple threads without external synchronization.
Structs§
- Virt
Queue - A split virtqueue managing descriptors, available ring, and used ring.
- Virtq
Avail - Available ring: driver writes descriptor chain heads here for the device to consume.
- Virtq
Desc - Virtqueue descriptor table entry.
- Virtq
Used - Used ring: device writes completed descriptor chain heads here.
- Virtq
Used Elem - Element in the used ring, returned by the device after processing.
Constants§
- DEFAULT_
QUEUE_ SIZE - Default queue size (power of 2, must match QEMU’s virtio-blk queue size). Legacy virtio requires the driver to use the exact queue size reported by the device. QEMU’s virtio-blk reports 256.
- VIRTQ_
DESC_ F_ INDIRECT - Descriptor flag: buffer contains a list of buffer descriptors (indirect)
- VIRTQ_
DESC_ F_ NEXT - Descriptor flag: buffer continues via the
nextfield - VIRTQ_
DESC_ F_ WRITE - Descriptor flag: buffer is device-writable (device writes, driver reads)