Skip to content

Commit aa4771d

Browse files
kornelskimajek
authored andcommitted
Improve vqueue abstractions: use iterators for VirtioDevice.queues()
Signed-off-by: Kornel Lesiński <[email protected]>
1 parent 27d44cb commit aa4771d

File tree

13 files changed

+106
-76
lines changed

13 files changed

+106
-76
lines changed

src/vmm/src/device_manager/mmio.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ mod tests {
467467

468468
use super::*;
469469
use crate::devices::virtio::device::VirtioDevice;
470-
use crate::devices::virtio::queue::Queue;
470+
use crate::devices::virtio::queue::{Queue, QueueIter, QueueIterMut};
471471
use crate::devices::virtio::ActivateError;
472472
use crate::vstate::memory::{GuestAddress, GuestMemoryExtension, GuestMemoryMmap};
473473
use crate::{builder, Vm};
@@ -535,12 +535,12 @@ mod tests {
535535
0
536536
}
537537

538-
fn queues(&self) -> &[Queue] {
539-
&self.queues
538+
fn queues(&self) -> QueueIter {
539+
self.queues.iter()
540540
}
541541

542-
fn queues_mut(&mut self) -> &mut [Queue] {
543-
&mut self.queues
542+
fn queues_mut(&mut self) -> QueueIterMut {
543+
self.queues.iter_mut()
544544
}
545545

546546
fn queue_events(&self) -> &[EventFd] {

src/vmm/src/devices/virtio/balloon/device.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use utils::eventfd::EventFd;
1414
use utils::u64_to_usize;
1515

1616
use super::super::device::{DeviceState, VirtioDevice};
17-
use super::super::queue::Queue;
1817
use super::super::{ActivateError, TYPE_BALLOON};
1918
use super::metrics::METRICS;
2019
use super::util::{compact_page_frame_numbers, remove_range};
@@ -30,6 +29,7 @@ use super::{
3029
use crate::devices::virtio::balloon::BalloonError;
3130
use crate::devices::virtio::device::{IrqTrigger, IrqType};
3231
use crate::devices::virtio::gen::virtio_blk::VIRTIO_F_VERSION_1;
32+
use crate::devices::virtio::queue::{Queue, QueueIter, QueueIterMut};
3333
use crate::logger::IncMetric;
3434
use crate::vstate::memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryMmap};
3535

@@ -573,12 +573,12 @@ impl VirtioDevice for Balloon {
573573
TYPE_BALLOON
574574
}
575575

576-
fn queues(&self) -> &[Queue] {
577-
&self.queues
576+
fn queues(&self) -> QueueIter {
577+
self.queues.iter()
578578
}
579579

580-
fn queues_mut(&mut self) -> &mut [Queue] {
581-
&mut self.queues
580+
fn queues_mut(&mut self) -> QueueIterMut {
581+
self.queues.iter_mut()
582582
}
583583

584584
fn queue_events(&self) -> &[EventFd] {

src/vmm/src/devices/virtio/balloon/persist.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ mod tests {
209209
assert_eq!(restored_balloon.acked_features, balloon.acked_features);
210210
assert_eq!(restored_balloon.avail_features, balloon.avail_features);
211211
assert_eq!(restored_balloon.config_space, balloon.config_space);
212-
assert_eq!(restored_balloon.queues(), balloon.queues());
212+
assert!(restored_balloon.queues().eq(balloon.queues()));
213213
assert_eq!(
214214
restored_balloon.interrupt_status().load(Ordering::Relaxed),
215215
balloon.interrupt_status().load(Ordering::Relaxed)

src/vmm/src/devices/virtio/device.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use std::sync::Arc;
1212
use utils::eventfd::EventFd;
1313

1414
use super::mmio::{VIRTIO_MMIO_INT_CONFIG, VIRTIO_MMIO_INT_VRING};
15-
use super::queue::Queue;
1615
use super::ActivateError;
16+
use crate::devices::virtio::queue::{QueueIter, QueueIterMut};
1717
use crate::devices::virtio::AsAny;
1818
use crate::logger::{error, warn};
1919
use crate::vstate::memory::GuestMemoryMmap;
@@ -111,10 +111,10 @@ pub trait VirtioDevice: AsAny + Send {
111111
fn device_type(&self) -> u32;
112112

113113
/// Returns the device queues.
114-
fn queues(&self) -> &[Queue];
114+
fn queues(&self) -> QueueIter;
115115

116116
/// Returns a mutable reference to the device queues.
117-
fn queues_mut(&mut self) -> &mut [Queue];
117+
fn queues_mut(&mut self) -> QueueIterMut;
118118

119119
/// Returns the device queues event fds.
120120
fn queue_events(&self) -> &[EventFd];
@@ -190,6 +190,7 @@ impl fmt::Debug for dyn VirtioDevice {
190190
#[cfg(test)]
191191
pub(crate) mod tests {
192192
use super::*;
193+
use crate::devices::virtio::queue::{QueueIter, QueueIterMut};
193194

194195
impl IrqTrigger {
195196
pub fn has_pending_irq(&self, irq_type: IrqType) -> bool {
@@ -254,11 +255,11 @@ pub(crate) mod tests {
254255
todo!()
255256
}
256257

257-
fn queues(&self) -> &[Queue] {
258+
fn queues(&self) -> QueueIter {
258259
todo!()
259260
}
260261

261-
fn queues_mut(&mut self) -> &mut [Queue] {
262+
fn queues_mut(&mut self) -> QueueIterMut {
262263
todo!()
263264
}
264265

src/vmm/src/devices/virtio/mmio.rs

+40-25
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,7 @@ impl MmioTransport {
9797
}
9898

9999
fn are_queues_valid(&self) -> bool {
100-
self.locked_device()
101-
.queues()
102-
.iter()
103-
.all(|q| q.is_valid(&self.mem))
100+
self.locked_device().queues().all(|q| q.is_valid(&self.mem))
104101
}
105102

106103
fn with_queue<U, F>(&self, d: U, f: F) -> U
@@ -111,7 +108,7 @@ impl MmioTransport {
111108
match self
112109
.locked_device()
113110
.queues()
114-
.get(self.queue_select as usize)
111+
.nth(self.queue_select as usize)
115112
{
116113
Some(queue) => f(queue),
117114
None => d,
@@ -122,7 +119,7 @@ impl MmioTransport {
122119
if let Some(queue) = self
123120
.locked_device()
124121
.queues_mut()
125-
.get_mut(self.queue_select as usize)
122+
.nth(self.queue_select as usize)
126123
{
127124
f(queue);
128125
true
@@ -363,6 +360,7 @@ pub(crate) mod tests {
363360
use utils::u64_to_usize;
364361

365362
use super::*;
363+
use crate::devices::virtio::queue::{Queue, QueueIter, QueueIterMut};
366364
use crate::devices::virtio::ActivateError;
367365
use crate::vstate::memory::{GuestMemoryExtension, GuestMemoryMmap};
368366

@@ -417,12 +415,12 @@ pub(crate) mod tests {
417415
123
418416
}
419417

420-
fn queues(&self) -> &[Queue] {
421-
&self.queues
418+
fn queues(&self) -> QueueIter {
419+
self.queues.iter()
422420
}
423421

424-
fn queues_mut(&mut self) -> &mut [Queue] {
425-
&mut self.queues
422+
fn queues_mut(&mut self) -> QueueIterMut {
423+
self.queues.iter_mut()
426424
}
427425

428426
fn queue_events(&self) -> &[EventFd] {
@@ -482,15 +480,23 @@ pub(crate) mod tests {
482480
assert_eq!(d.with_queue(0, |q| q.max_size()), 16);
483481
assert!(d.with_queue_mut(|q| q.set_size(16)));
484482
assert_eq!(
485-
d.locked_device().queues()[d.queue_select as usize].size(),
483+
d.locked_device()
484+
.queues()
485+
.nth(d.queue_select as usize)
486+
.unwrap()
487+
.size(),
486488
16
487489
);
488490

489491
d.queue_select = 1;
490492
assert_eq!(d.with_queue(0, |q| q.max_size()), 32);
491493
assert!(d.with_queue_mut(|q| q.set_size(16)));
492494
assert_eq!(
493-
d.locked_device().queues()[d.queue_select as usize].size(),
495+
d.locked_device()
496+
.queues()
497+
.nth(d.queue_select as usize)
498+
.unwrap()
499+
.size(),
494500
16
495501
);
496502

@@ -673,43 +679,52 @@ pub(crate) mod tests {
673679
assert_eq!(d.queue_select, 3);
674680

675681
d.queue_select = 0;
676-
assert_eq!(d.locked_device().queues()[0].size(), 0);
682+
assert_eq!(d.locked_device().queues().nth(0).unwrap().size(), 0);
677683
write_le_u32(&mut buf[..], 16);
678684
d.bus_write(0x38, &buf[..]);
679-
assert_eq!(d.locked_device().queues()[0].size(), 16);
685+
assert_eq!(d.locked_device().queues().nth(0).unwrap().size(), 16);
680686

681-
assert!(!d.locked_device().queues()[0].ready());
687+
assert!(!d.locked_device().queues().nth(0).unwrap().ready());
682688
write_le_u32(&mut buf[..], 1);
683689
d.bus_write(0x44, &buf[..]);
684-
assert!(d.locked_device().queues()[0].ready());
690+
assert!(d.locked_device().queues().nth(0).unwrap().ready());
685691

686-
assert_eq!(d.locked_device().queues()[0].desc_table().0, 0);
692+
assert_eq!(d.locked_device().queues().nth(0).unwrap().desc_table().0, 0);
687693
write_le_u32(&mut buf[..], 123);
688694
d.bus_write(0x80, &buf[..]);
689-
assert_eq!(d.locked_device().queues()[0].desc_table().0, 123);
695+
assert_eq!(
696+
d.locked_device().queues().nth(0).unwrap().desc_table().0,
697+
123
698+
);
690699
d.bus_write(0x84, &buf[..]);
691700
assert_eq!(
692-
d.locked_device().queues()[0].desc_table().0,
701+
d.locked_device().queues().nth(0).unwrap().desc_table().0,
693702
123 + (123 << 32)
694703
);
695704

696-
assert_eq!(d.locked_device().queues()[0].avail_ring().0, 0);
705+
assert_eq!(d.locked_device().queues().nth(0).unwrap().avail_ring().0, 0);
697706
write_le_u32(&mut buf[..], 124);
698707
d.bus_write(0x90, &buf[..]);
699-
assert_eq!(d.locked_device().queues()[0].avail_ring().0, 124);
708+
assert_eq!(
709+
d.locked_device().queues().nth(0).unwrap().avail_ring().0,
710+
124
711+
);
700712
d.bus_write(0x94, &buf[..]);
701713
assert_eq!(
702-
d.locked_device().queues()[0].avail_ring().0,
714+
d.locked_device().queues().nth(0).unwrap().avail_ring().0,
703715
124 + (124 << 32)
704716
);
705717

706-
assert_eq!(d.locked_device().queues()[0].used_ring().0, 0);
718+
assert_eq!(d.locked_device().queues().nth(0).unwrap().used_ring().0, 0);
707719
write_le_u32(&mut buf[..], 125);
708720
d.bus_write(0xa0, &buf[..]);
709-
assert_eq!(d.locked_device().queues()[0].used_ring().0, 125);
721+
assert_eq!(
722+
d.locked_device().queues().nth(0).unwrap().used_ring().0,
723+
125
724+
);
710725
d.bus_write(0xa4, &buf[..]);
711726
assert_eq!(
712-
d.locked_device().queues()[0].used_ring().0,
727+
d.locked_device().queues().nth(0).unwrap().used_ring().0,
713728
125 + (125 << 32)
714729
);
715730

src/vmm/src/devices/virtio/net/device.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::devices::virtio::net::tap::Tap;
3333
use crate::devices::virtio::net::{
3434
gen, NetError, NetQueue, MAX_BUFFER_SIZE, NET_QUEUE_SIZES, RX_INDEX, TX_INDEX,
3535
};
36-
use crate::devices::virtio::queue::{DescriptorChain, Queue};
36+
use crate::devices::virtio::queue::{DescriptorChain, Queue, QueueIter, QueueIterMut};
3737
use crate::devices::virtio::{ActivateError, TYPE_NET};
3838
use crate::devices::{report_net_event_fail, DeviceError};
3939
use crate::dumbo::pdu::arp::ETH_IPV4_FRAME_LEN;
@@ -787,12 +787,12 @@ impl VirtioDevice for Net {
787787
TYPE_NET
788788
}
789789

790-
fn queues(&self) -> &[Queue] {
791-
&self.queues
790+
fn queues(&self) -> QueueIter {
791+
self.queues.iter()
792792
}
793793

794-
fn queues_mut(&mut self) -> &mut [Queue] {
795-
&mut self.queues
794+
fn queues_mut(&mut self) -> QueueIterMut {
795+
self.queues.iter_mut()
796796
}
797797

798798
fn queue_events(&self) -> &[EventFd] {
@@ -845,7 +845,7 @@ impl VirtioDevice for Net {
845845
fn activate(&mut self, mem: GuestMemoryMmap) -> Result<(), ActivateError> {
846846
let event_idx = self.has_feature(u64::from(VIRTIO_RING_F_EVENT_IDX));
847847
if event_idx {
848-
for queue in &mut self.queues {
848+
for queue in self.queues_mut() {
849849
queue.enable_notif_suppression();
850850
}
851851
}
@@ -2007,10 +2007,9 @@ pub mod tests {
20072007
let net = th.net.lock().unwrap();
20082008

20092009
// Test queues count (TX and RX).
2010-
let queues = net.queues();
2011-
assert_eq!(queues.len(), NET_QUEUE_SIZES.len());
2012-
assert_eq!(queues[RX_INDEX].size(), th.rxq.size());
2013-
assert_eq!(queues[TX_INDEX].size(), th.txq.size());
2010+
assert_eq!(net.queues().count(), NET_QUEUE_SIZES.len());
2011+
assert_eq!(net.queues().nth(RX_INDEX).unwrap().size(), th.rxq.size());
2012+
assert_eq!(net.queues().nth(TX_INDEX).unwrap().size(), th.txq.size());
20142013

20152014
// Test corresponding queues events.
20162015
assert_eq!(net.queue_events().len(), NET_QUEUE_SIZES.len());
@@ -2028,8 +2027,7 @@ pub mod tests {
20282027
th.activate_net();
20292028

20302029
let net = th.net();
2031-
let queues = net.queues();
2032-
assert!(queues[RX_INDEX].uses_notif_suppression());
2033-
assert!(queues[TX_INDEX].uses_notif_suppression());
2030+
assert!(net.queues().nth(RX_INDEX).unwrap().uses_notif_suppression());
2031+
assert!(net.queues().nth(TX_INDEX).unwrap().uses_notif_suppression());
20342032
}
20352033
}

src/vmm/src/devices/virtio/persist.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl VirtioDeviceState {
118118
device_type: device.device_type(),
119119
avail_features: device.avail_features(),
120120
acked_features: device.acked_features(),
121-
queues: device.queues().iter().map(Persist::save).collect(),
121+
queues: device.queues().map(Persist::save).collect(),
122122
interrupt_status: device.interrupt_status().load(Ordering::Relaxed),
123123
interrupt_status_old: device.interrupt_status().load(Ordering::Relaxed) as usize,
124124
activated: device.is_activated(),

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

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub enum QueueError {
3636
UsedRing(#[from] vm_memory::GuestMemoryError),
3737
}
3838

39+
pub type QueueIter<'a> = std::slice::Iter<'a, Queue>;
40+
pub type QueueIterMut<'a> = std::slice::IterMut<'a, Queue>;
41+
3942
/// A virtio descriptor constraints with C representative.
4043
#[repr(C)]
4144
#[derive(Default, Clone, Copy)]

src/vmm/src/devices/virtio/rng/device.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::devices::virtio::device::{DeviceState, IrqTrigger, IrqType, VirtioDev
1515
use crate::devices::virtio::gen::virtio_rng::VIRTIO_F_VERSION_1;
1616
use crate::devices::virtio::iovec::IoVecBufferMut;
1717
use crate::devices::virtio::queue::{Queue, FIRECRACKER_MAX_QUEUE_SIZE};
18+
use crate::devices::virtio::queue::{QueueIter, QueueIterMut};
1819
use crate::devices::virtio::{ActivateError, TYPE_RNG};
1920
use crate::devices::DeviceError;
2021
use crate::logger::{debug, error, IncMetric};
@@ -246,12 +247,12 @@ impl VirtioDevice for Entropy {
246247
TYPE_RNG
247248
}
248249

249-
fn queues(&self) -> &[Queue] {
250-
&self.queues
250+
fn queues(&self) -> QueueIter {
251+
self.queues.iter()
251252
}
252253

253-
fn queues_mut(&mut self) -> &mut [Queue] {
254-
&mut self.queues
254+
fn queues_mut(&mut self) -> QueueIterMut {
255+
self.queues.iter_mut()
255256
}
256257

257258
fn queue_events(&self) -> &[EventFd] {
@@ -430,14 +431,24 @@ mod tests {
430431
let mut entropy_dev = th.device();
431432

432433
// This should succeed, we just added two descriptors
433-
let desc = entropy_dev.queues_mut()[RNG_QUEUE].pop(&mem).unwrap();
434+
let desc = entropy_dev
435+
.queues_mut()
436+
.nth(RNG_QUEUE)
437+
.unwrap()
438+
.pop(&mem)
439+
.unwrap();
434440
assert!(matches!(
435441
IoVecBufferMut::from_descriptor_chain(&mem, desc,),
436442
Err(crate::devices::virtio::iovec::IoVecError::ReadOnlyDescriptor)
437443
));
438444

439445
// This should succeed, we should have one more descriptor
440-
let desc = entropy_dev.queues_mut()[RNG_QUEUE].pop(&mem).unwrap();
446+
let desc = entropy_dev
447+
.queues_mut()
448+
.nth(RNG_QUEUE)
449+
.unwrap()
450+
.pop(&mem)
451+
.unwrap();
441452
let mut iovec = IoVecBufferMut::from_descriptor_chain(&mem, desc).unwrap();
442453
assert!(entropy_dev.handle_one(&mut iovec).is_ok());
443454
}

0 commit comments

Comments
 (0)