pub struct SplitQueue { /* private fields */ }Expand description
A VirtIO split virtqueue backed by guest physical memory.
Implementations§
Source§impl SplitQueue
impl SplitQueue
Sourcepub fn new(
mem: Arc<GuestMemWriter>,
queue_idx: u16,
cfg: &QueueConfig,
event_idx: bool,
) -> Self
pub fn new( mem: Arc<GuestMemWriter>, queue_idx: u16, cfg: &QueueConfig, event_idx: bool, ) -> Self
Builds a queue from the MMIO-configured ring addresses. Called at
QUEUE_READY time; last_avail_idx/used_idx start fresh (the guest
sets up zeroed rings before marking the queue ready).
Sourcepub const fn last_avail_idx(&self) -> u16
pub const fn last_avail_idx(&self) -> u16
The next available-ring index this queue will consume.
Sourcepub const fn set_last_avail_idx(&mut self, idx: u16)
pub const fn set_last_avail_idx(&mut self, idx: u16)
Seeds the available-ring cursor. Used when a device persists its avail position across calls and reconstructs the queue transiently.
Sourcepub fn mem(&self) -> &GuestMemWriter
pub fn mem(&self) -> &GuestMemWriter
Guest memory accessor for reading/writing descriptor buffers by GPA.
Sourcepub fn set_event_idx(&mut self, enabled: bool)
pub fn set_event_idx(&mut self, enabled: bool)
Enable or disable EVENT_IDX notification suppression.
Sourcepub fn pop_avail(&mut self) -> Option<DescChain>
pub fn pop_avail(&mut self) -> Option<DescChain>
Pops the next available descriptor chain, or None if the ring is empty.
The chain walk is bounded by size: a cyclic next chain from a
malformed or malicious guest terminates instead of spinning.
Sourcepub fn next_avail_head(&mut self) -> Option<u16>
pub fn next_avail_head(&mut self) -> Option<u16>
Pops the next available chain head, advancing the avail cursor, or
returns None if the ring is empty. Pair with Self::chain_iter for
an allocation-free chain walk on per-packet hot paths.
Sourcepub fn chain_iter(&self, head: u16) -> ChainIter<'_> ⓘ
pub fn chain_iter(&self, head: u16) -> ChainIter<'_> ⓘ
Returns an allocation-free iterator over the descriptor chain starting
at head. Bounded by the queue size so a cyclic next chain
terminates. Each yielded descriptor’s addr is a GPA; access its buffer
through Self::mem.
Sourcepub fn push_used(&mut self, head_idx: u16, len: u32) -> bool
pub fn push_used(&mut self, head_idx: u16, len: u32) -> bool
Publishes a single completion. Returns whether the guest must be
interrupted (see Self::should_notify).
Sourcepub fn push_used_batch(&mut self, completions: &[(u16, u32)]) -> bool
pub fn push_used_batch(&mut self, completions: &[(u16, u32)]) -> bool
Publishes a batch of completions with a single used.idx update and one
suppression check. Returns whether to interrupt the guest.
Sourcepub fn write_avail_event(&self)
pub fn write_avail_event(&self)
Publishes avail_event = last consumed avail index into the used ring,
so an EVENT_IDX guest kicks on its very next available entry. Call after
draining a guest→host queue so an isolated late entry can’t sit
undrained behind kick suppression.
Sourcepub fn write_avail_event_current(&self)
pub fn write_avail_event_current(&self)
Publishes avail_event = the guest's current avail.idx, requesting a
kick only for entries posted beyond everything currently visible.
For polling consumers that never need guest kicks (the net RX inject
thread re-reads avail.idx on every attempt), this maximally
suppresses the guest’s QUEUE_NOTIFY MMIO exits, whereas
Self::write_avail_event (consumed cursor) is for drain-then-sleep
consumers that must be kicked for the very next entry.
The Release fence orders prior used-ring writes before the
avail_event store, pairing with the guest’s acquire on the used ring.
Sourcepub fn enable_notification(&self) -> bool
pub fn enable_notification(&self) -> bool
Re-arms guest→host notifications and reports whether the guest made more entries available while we were draining.
Publishes avail_event (so an EVENT_IDX guest kicks on its next entry),
inserts a SeqCst StoreLoad barrier, then re-reads avail.idx. Returns
true if the ring advanced past what we consumed — the caller must drain
again. This is the device half of the EVENT_IDX handshake: without the
barrier + re-check, a buffer the guest adds (and skips the kick for,
having read the pre-update avail_event) just as we stop polling sits
undrained forever. Mirrors virtio-queue/libkrun enable_notification.