Skip to content

Commit 59b0681

Browse files
committed
feat(virtio): split add_used() into 2 separate methods
`Queue::add_used()` method first writes a Descriptor head in the used descriptor ring buffer and then advances the index of this buffer to let the guest know we used one or more Descriptors. Carve out each one of these steps in their own function so that we can add multiple descriptors in the used ring and advance the index only once we finish handling descriptors in one step. This will be useful when, in later commits, we will implement RX_MRGBUF for the RX queue of the network device Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent aa0dca9 commit 59b0681

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

src/vmm/src/devices/virtio/queue.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,16 @@ impl Queue {
574574
self.next_avail -= Wrapping(1);
575575
}
576576

577-
/// Puts an available descriptor head into the used ring for use by the guest.
578-
pub fn add_used(&mut self, desc_index: u16, len: u32) -> Result<(), QueueError> {
577+
/// Write used element into used_ring ring.
578+
/// - [`ring_index_offset`] is an offset added to
579+
/// the current [`self.next_used`] to obtain actual index
580+
/// into used_ring.
581+
pub fn write_used_element(
582+
&mut self,
583+
ring_index_offset: u16,
584+
desc_index: u16,
585+
len: u32,
586+
) -> Result<(), QueueError> {
579587
if self.actual_size() <= desc_index {
580588
error!(
581589
"attempted to add out of bounds descriptor to used ring: {}",
@@ -584,7 +592,7 @@ impl Queue {
584592
return Err(QueueError::DescIndexOutOfBounds(desc_index));
585593
}
586594

587-
let next_used = self.next_used.0 % self.actual_size();
595+
let next_used = (self.next_used + Wrapping(ring_index_offset)).0 % self.actual_size();
588596
let used_element = UsedElement {
589597
id: u32::from(desc_index),
590598
len,
@@ -594,14 +602,24 @@ impl Queue {
594602
unsafe {
595603
self.used_ring_ring_set(usize::from(next_used), used_element);
596604
}
605+
Ok(())
606+
}
597607

598-
self.num_added += Wrapping(1);
599-
self.next_used += Wrapping(1);
608+
/// Advance queue and used ring by `n` elements.
609+
pub fn advance_used_ring(&mut self, n: u16) {
610+
self.num_added += Wrapping(n);
611+
self.next_used += Wrapping(n);
600612

601613
// This fence ensures all descriptor writes are visible before the index update is.
602614
fence(Ordering::Release);
603615

604616
self.used_ring_idx_set(self.next_used.0);
617+
}
618+
619+
/// Puts an available descriptor head into the used ring for use by the guest.
620+
pub fn add_used(&mut self, desc_index: u16, len: u32) -> Result<(), QueueError> {
621+
self.write_used_element(0, desc_index, len)?;
622+
self.advance_used_ring(1);
605623
Ok(())
606624
}
607625

0 commit comments

Comments
 (0)