Skip to main content

Module queue

Module queue 

Source
Expand description

Split-ring virtqueue handling.

Implements the classic split-ring layout from virtio v1.2 § 2.7. The packed-ring (VIRTIO_F_RING_PACKED, crate::feature_bits::RING_PACKED) is intentionally not implemented for 1.0 — split-ring is what every Firecracker-compat guest driver uses, and the simpler queue handler keeps the device modules small.

§Layout (per spec § 2.7)

Descriptor table:    desc_table_addr,  16 * queue_size bytes
Available ring:      avail_ring_addr,  6 + 2 * queue_size bytes
Used ring:           used_ring_addr,   6 + 8 * queue_size bytes

Each descriptor:

0x00 u64  addr     guest-physical address of the buffer
0x08 u32  len      buffer length in bytes
0x0C u16  flags    (NEXT | WRITE | INDIRECT)
0x0E u16  next     descriptor table index of the next descriptor

Available ring:

0x00 u16  flags
0x02 u16  idx        producer (driver) cursor
0x04 [u16; queue_size] ring   indices of descriptor heads

Used ring:

0x00 u16  flags
0x02 u16  idx                        producer (device) cursor
0x04 [(u32, u32); queue_size] ring   (head_index, total_bytes_written)

§Concurrency

The device handler thread “owns” the queue’s last_avail_idx cursor; the guest driver is the sole writer of avail.idx. The transport’s queue state lives behind the device’s mutex, so race-free across threads.

Structs§

Descriptor
One descriptor entry from a chain: a single guest buffer with its flags.
DescriptorChain
Iterator over the descriptors in a single chain (head + linked descriptors via NEXT).
Queue
Per-queue setup state and runtime cursor.
QueueIndex
Type-safe wrapper around a queue cursor index. Wraps modulo queue_size at the call site.

Enums§

QueueError
Queue / descriptor / ring errors.

Constants§

MAX_QUEUE_SIZE
Maximum allowed queue_size. Per spec § 2.7 it must be a power of two ≤ 32768. Squib’s per-device modules cap below this for memory pressure reasons; the spec ceiling is exposed so a future device that wants to push it can.
VIRTQ_DESC_F_INDIRECT
Descriptor flag: this descriptor’s buffer holds an indirect descriptor table.
VIRTQ_DESC_F_NEXT
Descriptor flag: another descriptor follows in the chain (next field is valid).
VIRTQ_DESC_F_WRITE
Descriptor flag: descriptor is device-write (the device fills it).