Struct virtio_queue::Queue
source · [−]pub struct Queue<M: GuestAddressSpace, S: QueueStateT = QueueState> {
pub mem: M,
pub state: S,
}
Expand description
A convenient wrapper struct for a virtio queue, with associated GuestMemory
object.
Example
use virtio_queue::{Queue, QueueState};
use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryMmap};
let m = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10000)]).unwrap();
let mut queue = Queue::<&GuestMemoryMmap, QueueState>::new(&m, 1024);
// 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());
// 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().unwrap();
// Consume entries from the available ring.
while let Some(chain) = queue.iter().unwrap().next() {
// Process the descriptor chain, and then add an entry in the used ring and optionally
// notify the driver.
queue.add_used(chain.head_index(), 0x100).unwrap();
if queue.needs_notification().unwrap() {
// Here we would notify the driver it has new entries in the used ring to consume.
}
}
if !queue.enable_notification().unwrap() {
break;
}
}
// We can reset the queue at some point.
queue.reset();
// The queue should not be ready after reset.
assert!(!queue.ready());
Fields
mem: M
Guest memory object associated with the queue.
state: S
Virtio queue state.
Implementations
sourceimpl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S>
impl<M: GuestAddressSpace, S: QueueStateT> Queue<M, S>
sourcepub fn new(mem: M, max_size: u16) -> Self
pub fn new(mem: M, max_size: u16) -> Self
Construct an empty virtio queue with the given max_size
.
Arguments
mem
- the guest memory object that can be used to access the queue buffers.max_size
- the maximum size (and the default one) of the queue.
sourcepub fn lock(&mut self) -> <S as QueueStateGuard<'_>>::G
pub fn lock(&mut self) -> <S as QueueStateGuard<'_>>::G
Get an exclusive reference to the underlying QueueState
object.
Logically this method will acquire the underlying lock protecting the QueueState
Object.
The lock will be released when the returned object gets dropped.
sourcepub fn lock_with_memory(
&mut self
) -> QueueGuard<<M as GuestAddressSpace>::T, <S as QueueStateGuard<'_>>::G>
pub fn lock_with_memory(
&mut self
) -> QueueGuard<<M as GuestAddressSpace>::T, <S as QueueStateGuard<'_>>::G>
Get an exclusive reference to the underlying QueueState
object with an associated
GuestMemory
object.
Logically this method will acquire the underlying lock protecting the QueueState
Object.
The lock will be released when the returned object gets dropped.
sourcepub fn set_size(&mut self, size: u16)
pub fn set_size(&mut self, size: u16)
Configure the queue size for the virtio queue.
Arguments
size
- the queue size; it should be a power of two, different than 0 and less than or equal to the value reported bymax_size()
, otherwise the queue size remains the default one (which is the maximum one).
sourcepub fn set_ready(&mut self, ready: bool)
pub fn set_ready(&mut self, ready: bool)
Configure the queue to the ready for processing
state.
Arguments
ready
- a boolean to indicate whether the queue is ready to be used or not.
sourcepub fn set_desc_table_address(&mut self, low: Option<u32>, high: Option<u32>)
pub fn set_desc_table_address(&mut self, low: Option<u32>, high: Option<u32>)
Set the descriptor table address for the queue.
The descriptor table address is 64-bit, the corresponding part will be updated if ‘low’
and/or high
is Some
and valid.
Arguments
low
- an optional value for the lowest 32 bits of the address.high
- an optional value for the highest 32 bits of the address.
sourcepub fn set_avail_ring_address(&mut self, low: Option<u32>, high: Option<u32>)
pub fn set_avail_ring_address(&mut self, low: Option<u32>, high: Option<u32>)
Set the available ring address for the queue.
The available ring address is 64-bit, the corresponding part will be updated if ‘low’
and/or high
is Some
and valid.
Arguments
low
- an optional value for the lowest 32 bits of the address.high
- an optional value for the highest 32 bits of the address.
sourcepub fn set_used_ring_address(&mut self, low: Option<u32>, high: Option<u32>)
pub fn set_used_ring_address(&mut self, low: Option<u32>, high: Option<u32>)
Set the used ring address for the queue.
The used ring address is 64-bit, the corresponding part will be updated if ‘low’
and/or high
is Some
and valid.
Arguments
low
- an optional value for the lowest 32 bits of the address.high
- an optional value for the highest 32 bits of the address.
sourcepub fn set_event_idx(&mut self, enabled: bool)
pub fn set_event_idx(&mut self, enabled: bool)
Enable/disable the VIRTIO_F_RING_EVENT_IDX feature for interrupt coalescing.
Arguments
enabled
- a boolean to indicate whether the VIRTIO_F_RING_EVENT_IDX feature was successfully negotiated or not.
sourcepub fn avail_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error>
pub fn avail_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error>
Read the idx
field from the available ring.
Arguments
order
- the memory ordering used to access theidx
field from memory.
sourcepub fn used_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error>
pub fn used_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error>
Reads the idx
field from the used ring.
Arguments
order
- the memory ordering used to access theidx
field from memory.
sourcepub fn add_used(&mut self, head_index: u16, len: u32) -> Result<(), Error>
pub fn add_used(&mut self, head_index: u16, len: u32) -> Result<(), Error>
Put a used descriptor head into the used ring.
Arguments
head_index
- the index of the used descriptor chain.len
- the total length of the descriptor chain which was used (written to).
sourcepub fn enable_notification(&mut self) -> Result<bool, Error>
pub fn enable_notification(&mut self) -> Result<bool, Error>
Enable notification events from the guest driver.
Return true if one or more descriptors can be consumed from the available ring after notifications were enabled (and thus it’s possible there will be no corresponding notification).
sourcepub fn disable_notification(&mut self) -> Result<(), Error>
pub fn disable_notification(&mut self) -> Result<(), Error>
Disable notification events from the guest driver.
sourcepub fn needs_notification(&mut self) -> Result<bool, Error>
pub fn needs_notification(&mut self) -> Result<bool, Error>
Check whether a notification to the guest is needed.
Please note this method has side effects: once it returns true
, it considers the
driver will actually be notified, remember the associated index in the used ring, and
won’t return true
again until the driver updates used_event
and/or the notification
conditions hold once more.
sourcepub fn next_avail(&self) -> u16
pub fn next_avail(&self) -> u16
Return the index of the next entry in the available ring.
sourcepub fn set_next_avail(&mut self, next_avail: u16)
pub fn set_next_avail(&mut self, next_avail: u16)
Set the index of the next entry in the available ring.
Arguments
next_avail
- the index of the next available ring entry.
sourcepub fn set_next_used(&mut self, next_used: u16)
pub fn set_next_used(&mut self, next_used: u16)
Sets the index for the next descriptor in the used ring.
Arguments
next_used
- the index of the next used ring entry.
sourceimpl<M: GuestAddressSpace> Queue<M, QueueState>
impl<M: GuestAddressSpace> Queue<M, QueueState>
Trait Implementations
sourceimpl<M: Clone + GuestAddressSpace, S: Clone + QueueStateT> Clone for Queue<M, S>
impl<M: Clone + GuestAddressSpace, S: Clone + QueueStateT> Clone for Queue<M, S>
Auto Trait Implementations
impl<M, S> RefUnwindSafe for Queue<M, S> where
M: RefUnwindSafe,
S: RefUnwindSafe,
impl<M, S> Send for Queue<M, S> where
M: Send,
S: Send,
impl<M, S> Sync for Queue<M, S> where
M: Sync,
S: Sync,
impl<M, S> Unpin for Queue<M, S> where
M: Unpin,
S: Unpin,
impl<M, S> UnwindSafe for Queue<M, S> where
M: UnwindSafe,
S: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more