Struct virtio_queue::Queue

source ·
pub struct Queue { /* private fields */ }
Expand description

Struct to maintain information and manipulate a virtio queue.

§Example

use virtio_queue::{Queue, QueueOwnedT, QueueT};
use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryMmap};

let m = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let mut queue = Queue::new(1024).unwrap();

// First, the driver sets up the queue; this set up is done via writes on the bus (PCI, MMIO).
queue.set_size(8);
queue.set_desc_table_address(Some(0x1000), None);
queue.set_avail_ring_address(Some(0x2000), None);
queue.set_used_ring_address(Some(0x3000), None);
queue.set_event_idx(true);
queue.set_ready(true);
// The user should check if the queue is valid before starting to use it.
assert!(queue.is_valid(&m));

// Here the driver would add entries in the available ring and then update the `idx` field of
// the available ring (address = 0x2000 + 2).
m.write_obj(3, GuestAddress(0x2002));

loop {
    queue.disable_notification(&m).unwrap();

    // Consume entries from the available ring.
    while let Some(chain) = queue.iter(&m).unwrap().next() {
        // Process the descriptor chain, and then add an entry in the used ring and optionally
        // notify the driver.
        queue.add_used(&m, chain.head_index(), 0x100).unwrap();

        if queue.needs_notification(&m).unwrap() {
            // Here we would notify the driver it has new entries in the used ring to consume.
        }
    }
    if !queue.enable_notification(&m).unwrap() {
        break;
    }
}

// We can reset the queue at some point.
queue.reset();
// The queue should not be ready after reset.
assert!(!queue.ready());

Implementations§

source§

impl Queue

source

pub fn try_set_size(&mut self, size: u16) -> Result<(), Error>

Equivalent of QueueT::set_size returning an error in case of invalid size.

This should not be directly used, as the preferred method is part of the QueueT interface. This is a convenience function for implementing save/restore capabilities.

source

pub fn try_set_desc_table_address( &mut self, desc_table: GuestAddress ) -> Result<(), Error>

Tries to set the descriptor table address. In case of an invalid value, the address is not updated.

This should not be directly used, as the preferred method is QueueT::set_desc_table_address. This is a convenience function for implementing save/restore capabilities.

source

pub fn try_set_avail_ring_address( &mut self, avail_ring: GuestAddress ) -> Result<(), Error>

Tries to update the available ring address. In case of an invalid value, the address is not updated.

This should not be directly used, as the preferred method is QueueT::set_avail_ring_address. This is a convenience function for implementing save/restore capabilities.

source

pub fn try_set_used_ring_address( &mut self, used_ring: GuestAddress ) -> Result<(), Error>

Tries to update the used ring address. In cae of an invalid value, the address is not updated.

This should not be directly used, as the preferred method is QueueT::set_used_ring_address. This is a convenience function for implementing save/restore capabilities.

source

pub fn state(&self) -> QueueState

Returns the state of the Queue.

This is useful for implementing save/restore capabilities. The state does not have support for serialization, but this can be added by VMMs locally through the use of a remote type.

Alternatively, a version aware and serializable/deserializable QueueState is available in the virtio-queue-ser crate.

Trait Implementations§

source§

impl Debug for Queue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Queue

source§

fn default() -> Queue

Returns the “default value” for a type. Read more
source§

impl PartialEq for Queue

source§

fn eq(&self, other: &Queue) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<'a> QueueGuard<'a> for Queue

§

type G = &'a mut Queue

Type for guard returned by Self::lock().
source§

impl QueueOwnedT for Queue

source§

fn iter<M>(&mut self, mem: M) -> Result<AvailIter<'_, M>, Error>
where M: Deref, M::Target: GuestMemory,

Get a consuming iterator over all available descriptor chain heads offered by the driver. Read more
source§

fn go_to_previous_position(&mut self)

Undo the last advancement of the next available index field by decrementing its value by one.
source§

impl QueueT for Queue

source§

fn new(max_size: u16) -> Result<Self, Error>

Construct an empty virtio queue state object with the given max_size. Read more
source§

fn is_valid<M: GuestMemory>(&self, mem: &M) -> bool

Check whether the queue configuration is valid.
source§

fn reset(&mut self)

Reset the queue to the initial state.
source§

fn lock(&mut self) -> <Self as QueueGuard<'_>>::G

Get an exclusive reference to the underlying Queue object. Read more
source§

fn max_size(&self) -> u16

Get the maximum size of the virtio queue.
source§

fn size(&self) -> u16

Get the actual size configured by the guest.
source§

fn set_size(&mut self, size: u16)

Configure the queue size for the virtio queue.
source§

fn ready(&self) -> bool

Check whether the queue is ready to be processed.
source§

fn set_ready(&mut self, ready: bool)

Configure the queue to ready for processing state.
source§

fn set_desc_table_address(&mut self, low: Option<u32>, high: Option<u32>)

Set the descriptor table address for the queue. Read more
source§

fn set_avail_ring_address(&mut self, low: Option<u32>, high: Option<u32>)

Set the available ring address for the queue. Read more
source§

fn set_used_ring_address(&mut self, low: Option<u32>, high: Option<u32>)

Set the used ring address for the queue. Read more
source§

fn set_event_idx(&mut self, enabled: bool)

Enable/disable the VIRTIO_F_RING_EVENT_IDX feature for interrupt coalescing.
source§

fn avail_idx<M>(&self, mem: &M, order: Ordering) -> Result<Wrapping<u16>, Error>
where M: GuestMemory + ?Sized,

Read the idx field from the available ring. Read more
source§

fn used_idx<M: GuestMemory>( &self, mem: &M, order: Ordering ) -> Result<Wrapping<u16>, Error>

Read the idx field from the used ring. Read more
source§

fn add_used<M: GuestMemory>( &mut self, mem: &M, head_index: u16, len: u32 ) -> Result<(), Error>

Put a used descriptor head into the used ring.
source§

fn enable_notification<M: GuestMemory>( &mut self, mem: &M ) -> Result<bool, Error>

Enable notification events from the guest driver. Read more
source§

fn disable_notification<M: GuestMemory>(&mut self, mem: &M) -> Result<(), Error>

Disable notification events from the guest driver.
source§

fn needs_notification<M: GuestMemory>(&mut self, mem: &M) -> Result<bool, Error>

Check whether a notification to the guest is needed. Read more
source§

fn next_avail(&self) -> u16

Return the index of the next entry in the available ring.
source§

fn set_next_avail(&mut self, next_avail: u16)

Set the index of the next entry in the available ring.
source§

fn next_used(&self) -> u16

Return the index for the next descriptor in the used ring.
source§

fn set_next_used(&mut self, next_used: u16)

Set the index for the next descriptor in the used ring.
source§

fn desc_table(&self) -> u64

Return the address of the descriptor table.
source§

fn avail_ring(&self) -> u64

Return the address of the available ring.
source§

fn used_ring(&self) -> u64

Return the address of the used ring.
source§

fn event_idx_enabled(&self) -> bool

Checks whether VIRTIO_F_RING_EVENT_IDX is negotiated. Read more
source§

fn pop_descriptor_chain<M>(&mut self, mem: M) -> Option<DescriptorChain<M>>
where M: Clone + Deref, M::Target: GuestMemory,

Pop and return the next available descriptor chain, or None when there are no more descriptor chains available. Read more
source§

impl TryFrom<QueueState> for Queue

§

type Error = Error

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

fn try_from(q_state: QueueState) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl Eq for Queue

source§

impl StructuralPartialEq for Queue

Auto Trait Implementations§

§

impl Freeze for Queue

§

impl RefUnwindSafe for Queue

§

impl Send for Queue

§

impl Sync for Queue

§

impl Unpin for Queue

§

impl UnwindSafe for Queue

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>,

§

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>,

§

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.