Struct virtio_queue::QueueGuard
source · [−]pub struct QueueGuard<M, S> { /* private fields */ }
Expand description
A guard object to exclusively access an Queue
object.
The guard object holds an exclusive lock to the underlying QueueState
object, with an
associated guest memory object. It helps to guarantee that the whole session is served
with the same guest memory 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);
let mut queue_guard = queue.lock_with_memory();
// First, the driver sets up the queue; this set up is done via writes on the bus (PCI, MMIO).
queue_guard.set_size(8);
queue_guard.set_desc_table_address(Some(0x1000), None);
queue_guard.set_avail_ring_address(Some(0x2000), None);
queue_guard.set_used_ring_address(Some(0x3000), None);
queue_guard.set_event_idx(true);
queue_guard.set_ready(true);
// The user should check if the queue is valid before starting to use it.
assert!(queue_guard.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_guard.disable_notification().unwrap();
// Consume entries from the available ring.
while let Some(chain) = queue_guard.iter().unwrap().next() {
// Process the descriptor chain, and then add an entry in the used ring and optionally
// notify the driver.
queue_guard.add_used(chain.head_index(), 0x100).unwrap();
if queue_guard.needs_notification().unwrap() {
// Here we would notify the driver it has new entries in the used ring to consume.
}
}
if !queue_guard.enable_notification().unwrap() {
break;
}
}
Implementations
sourceimpl<M, S> QueueGuard<M, S> where
M: Deref + Clone,
M::Target: GuestMemory + Sized,
S: DerefMut<Target = QueueState>,
impl<M, S> QueueGuard<M, S> where
M: Deref + Clone,
M::Target: GuestMemory + Sized,
S: DerefMut<Target = QueueState>,
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.
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.
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.
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.
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.
sourcepub fn used_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error>
pub fn used_idx(&self, order: Ordering) -> Result<Wrapping<u16>, Error>
Read the idx
field from the used ring.
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.
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.
sourcepub fn set_next_used(&mut self, next_used: u16)
pub fn set_next_used(&mut self, next_used: u16)
Set the index of the next entry in the used ring.
sourcepub fn pop_descriptor_chain(&mut self) -> Option<DescriptorChain<M>>
pub fn pop_descriptor_chain(&mut self) -> Option<DescriptorChain<M>>
Pop and return the next available descriptor chain, or None
when there are no more
descriptor chains available.
sourcepub fn iter(&mut self) -> Result<AvailIter<'_, M>, Error>
pub fn iter(&mut self) -> Result<AvailIter<'_, M>, Error>
Get a consuming iterator over all available descriptor chain heads offered by the driver.
sourcepub fn go_to_previous_position(&mut self)
pub fn go_to_previous_position(&mut self)
Decrement the value of the next available index by one position.
Auto Trait Implementations
impl<M, S> RefUnwindSafe for QueueGuard<M, S> where
M: RefUnwindSafe,
S: RefUnwindSafe,
impl<M, S> Send for QueueGuard<M, S> where
M: Send,
S: Send,
impl<M, S> Sync for QueueGuard<M, S> where
M: Sync,
S: Sync,
impl<M, S> Unpin for QueueGuard<M, S> where
M: Unpin,
S: Unpin,
impl<M, S> UnwindSafe for QueueGuard<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