Skip to main content

SplitQueue

Struct SplitQueue 

Source
pub struct SplitQueue { /* private fields */ }
Expand description

A VirtIO split virtqueue backed by guest physical memory.

Implementations§

Source§

impl SplitQueue

Source

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).

Source

pub const fn last_avail_idx(&self) -> u16

The next available-ring index this queue will consume.

Source

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.

Source

pub const fn queue_idx(&self) -> u16

Queue index within the device.

Source

pub const fn size(&self) -> u16

Queue size (number of descriptors).

Source

pub fn mem(&self) -> &GuestMemWriter

Guest memory accessor for reading/writing descriptor buffers by GPA.

Source

pub fn set_event_idx(&mut self, enabled: bool)

Enable or disable EVENT_IDX notification suppression.

Source

pub fn has_avail(&self) -> bool

Whether there are available descriptors to process.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

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.

Source

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.

Source

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.

Trait Implementations§

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.