diff --git a/fuzz/fuzz_targets/block.rs b/fuzz/fuzz_targets/block.rs index 2d8b235a6..8ac1a93a0 100644 --- a/fuzz/fuzz_targets/block.rs +++ b/fuzz/fuzz_targets/block.rs @@ -84,9 +84,8 @@ fuzz_target!(|bytes| { q.state.ready = true; q.state.size = QUEUE_SIZE / 2; - let queue_evts: Vec = vec![EventFd::new(0).unwrap()]; - let queue_fd = queue_evts[0].as_raw_fd(); - let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(queue_fd)) }; + let evt = EventFd::new(0).unwrap(); + let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(evt.as_raw_fd())) }; let shm = memfd_create(&ffi::CString::new("fuzz").unwrap(), 0).unwrap(); let disk_file: File = unsafe { File::from_raw_fd(shm) }; @@ -110,8 +109,7 @@ fuzz_target!(|bytes| { .activate( guest_memory, Arc::new(NoopVirtioInterrupt {}), - vec![q], - queue_evts, + vec![(0, q, evt)], ) .ok(); diff --git a/virtio-devices/src/balloon.rs b/virtio-devices/src/balloon.rs index 0c523920b..d8b7c013f 100644 --- a/virtio-devices/src/balloon.rs +++ b/virtio-devices/src/balloon.rs @@ -542,17 +542,23 @@ impl VirtioDevice for Balloon { &mut self, _mem: GuestMemoryAtomic, interrupt_cb: Arc, - queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let (kill_evt, pause_evt) = self.common.dup_eventfds(); - let inflate_queue_evt = queue_evts.remove(0); - let deflate_queue_evt = queue_evts.remove(0); + let mut virtqueues = Vec::new(); + let (_, queue, queue_evt) = queues.remove(0); + virtqueues.push(queue); + let inflate_queue_evt = queue_evt; + let (_, queue, queue_evt) = queues.remove(0); + virtqueues.push(queue); + let deflate_queue_evt = queue_evt; let reporting_queue_evt = - if self.common.feature_acked(VIRTIO_BALLOON_F_REPORTING) && !queue_evts.is_empty() { - Some(queue_evts.remove(0)) + if self.common.feature_acked(VIRTIO_BALLOON_F_REPORTING) && !queues.is_empty() { + let (_, queue, queue_evt) = queues.remove(0); + virtqueues.push(queue); + Some(queue_evt) } else { None }; @@ -563,7 +569,7 @@ impl VirtioDevice for Balloon { error!("failed to clone resize EventFd: {:?}", e); ActivateError::BadActivate })?, - queues, + queues: virtqueues, interrupt_cb, inflate_queue_evt, deflate_queue_evt, diff --git a/virtio-devices/src/block.rs b/virtio-devices/src/block.rs index 00619ff07..408a40504 100644 --- a/virtio-devices/src/block.rs +++ b/virtio-devices/src/block.rs @@ -587,18 +587,16 @@ impl VirtioDevice for Block { &mut self, mem: GuestMemoryAtomic, interrupt_cb: Arc, - mut queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let disk_image_id = build_disk_image_id(&self.disk_path); self.update_writeback(); let mut epoll_threads = Vec::new(); for i in 0..queues.len() { - let queue_evt = queue_evts.remove(0); - let queue = queues.remove(0); + let (_, queue, queue_evt) = queues.remove(0); let queue_size = queue.state.size; let (kill_evt, pause_evt) = self.common.dup_eventfds(); diff --git a/virtio-devices/src/console.rs b/virtio-devices/src/console.rs index 98954db83..ea0a7cf2c 100644 --- a/virtio-devices/src/console.rs +++ b/virtio-devices/src/console.rs @@ -490,10 +490,9 @@ impl VirtioDevice for Console { &mut self, _mem: GuestMemoryAtomic, interrupt_cb: Arc, - queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; self.resizer .acked_features .store(self.common.acked_features, Ordering::Relaxed); @@ -507,13 +506,21 @@ impl VirtioDevice for Console { let (kill_evt, pause_evt) = self.common.dup_eventfds(); let input_evt = EventFd::new(EFD_NONBLOCK).unwrap(); + let mut virtqueues = Vec::new(); + let (_, queue, queue_evt) = queues.remove(0); + virtqueues.push(queue); + let input_queue_evt = queue_evt; + let (_, queue, queue_evt) = queues.remove(0); + virtqueues.push(queue); + let output_queue_evt = queue_evt; + let mut handler = ConsoleEpollHandler { - queues, + queues: virtqueues, interrupt_cb, in_buffer: self.in_buffer.clone(), endpoint: self.endpoint.clone(), - input_queue_evt: queue_evts.remove(0), - output_queue_evt: queue_evts.remove(0), + input_queue_evt, + output_queue_evt, input_evt, config_evt: self.resizer.config_evt.try_clone().unwrap(), resize_pipe: self.resize_pipe.as_ref().map(|p| p.try_clone().unwrap()), diff --git a/virtio-devices/src/device.rs b/virtio-devices/src/device.rs index 2cf54ba56..688bf2058 100644 --- a/virtio-devices/src/device.rs +++ b/virtio-devices/src/device.rs @@ -107,8 +107,7 @@ pub trait VirtioDevice: Send { &mut self, mem: GuestMemoryAtomic, interrupt_evt: Arc, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult; /// Optionally deactivates this device and returns ownership of the guest memory map, interrupt @@ -251,19 +250,9 @@ impl VirtioCommon { pub fn activate( &mut self, - queues: &[Queue>], - queue_evts: &[EventFd], + queues: &[(usize, Queue>, EventFd)], interrupt_cb: &Arc, ) -> ActivateResult { - if queues.len() != queue_evts.len() { - error!( - "Cannot activate: length mismatch: queue_evts={} queues={}", - queue_evts.len(), - queues.len() - ); - return Err(ActivateError::BadActivate); - } - if queues.len() < self.min_queues.into() { error!( "Number of enabled queues lower than min: {} vs {}", @@ -290,7 +279,7 @@ impl VirtioCommon { self.interrupt_cb = Some(interrupt_cb.clone()); let mut tmp_queue_evts: Vec = Vec::new(); - for queue_evt in queue_evts.iter() { + for (_, _, queue_evt) in queues.iter() { // Save the queue EventFD as we need to return it on reset // but clone it to pass into the thread. tmp_queue_evts.push(queue_evt.try_clone().map_err(|e| { diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index 8f86e0cce..6223fffe4 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -1052,13 +1052,20 @@ impl VirtioDevice for Iommu { &mut self, _mem: GuestMemoryAtomic, interrupt_cb: Arc, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let (kill_evt, pause_evt) = self.common.dup_eventfds(); + + let mut virtqueues = Vec::new(); + let mut queue_evts = Vec::new(); + for (_, queue, queue_evt) in queues { + virtqueues.push(queue); + queue_evts.push(queue_evt); + } + let mut handler = IommuEpollHandler { - queues, + queues: virtqueues, interrupt_cb, queue_evts, kill_evt, diff --git a/virtio-devices/src/mem.rs b/virtio-devices/src/mem.rs index 3f5e6d7db..555906e0a 100644 --- a/virtio-devices/src/mem.rs +++ b/virtio-devices/src/mem.rs @@ -1004,20 +1004,22 @@ impl VirtioDevice for Mem { &mut self, _mem: GuestMemoryAtomic, interrupt_cb: Arc, - mut queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let (kill_evt, pause_evt) = self.common.dup_eventfds(); + + let (_, queue, queue_evt) = queues.remove(0); + let mut handler = MemEpollHandler { host_addr: self.host_addr, host_fd: self.host_fd, blocks_state: Arc::clone(&self.blocks_state), config: self.config.clone(), resize: self.resize.clone(), - queue: queues.remove(0), + queue, interrupt_cb, - queue_evt: queue_evts.remove(0), + queue_evt, kill_evt, pause_evt, hugepages: self.hugepages, diff --git a/virtio-devices/src/net.rs b/virtio-devices/src/net.rs index d162e0cbb..3475a5cb4 100644 --- a/virtio-devices/src/net.rs +++ b/virtio-devices/src/net.rs @@ -585,17 +585,15 @@ impl VirtioDevice for Net { &mut self, _mem: GuestMemoryAtomic, interrupt_cb: Arc, - mut queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let num_queues = queues.len(); let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into()); if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && num_queues % 2 != 0 { let ctrl_queue_index = num_queues - 1; - let mut ctrl_queue = queues.remove(ctrl_queue_index); - let ctrl_queue_evt = queue_evts.remove(ctrl_queue_index); + let (_, mut ctrl_queue, ctrl_queue_evt) = queues.remove(ctrl_queue_index); ctrl_queue.set_event_idx(event_idx); @@ -641,11 +639,13 @@ impl VirtioDevice for Net { let tx = TxVirtio::new(); let rx_tap_listening = false; - let mut queue_pair = vec![queues.remove(0), queues.remove(0)]; + let (_, queue_0, queue_evt_0) = queues.remove(0); + let (_, queue_1, queue_evt_1) = queues.remove(0); + let mut queue_pair = vec![queue_0, queue_1]; queue_pair[0].set_event_idx(event_idx); queue_pair[1].set_event_idx(event_idx); - let queue_evt_pair = vec![queue_evts.remove(0), queue_evts.remove(0)]; + let queue_evt_pair = vec![queue_evt_0, queue_evt_1]; let (kill_evt, pause_evt) = self.common.dup_eventfds(); diff --git a/virtio-devices/src/pmem.rs b/virtio-devices/src/pmem.rs index 0cb7b0282..b623fef6e 100644 --- a/virtio-devices/src/pmem.rs +++ b/virtio-devices/src/pmem.rs @@ -379,21 +379,23 @@ impl VirtioDevice for Pmem { &mut self, _mem: GuestMemoryAtomic, interrupt_cb: Arc, - mut queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let (kill_evt, pause_evt) = self.common.dup_eventfds(); if let Some(disk) = self.disk.as_ref() { let disk = disk.try_clone().map_err(|e| { error!("failed cloning pmem disk: {}", e); ActivateError::BadActivate })?; + + let (_, queue, queue_evt) = queues.remove(0); + let mut handler = PmemEpollHandler { - queue: queues.remove(0), + queue, disk, interrupt_cb, - queue_evt: queue_evts.remove(0), + queue_evt, kill_evt, pause_evt, access_platform: self.common.access_platform.clone(), diff --git a/virtio-devices/src/rng.rs b/virtio-devices/src/rng.rs index a3a5c6e51..f8048047c 100644 --- a/virtio-devices/src/rng.rs +++ b/virtio-devices/src/rng.rs @@ -35,7 +35,7 @@ const QUEUE_SIZES: &[u16] = &[QUEUE_SIZE]; const QUEUE_AVAIL_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 1; struct RngEpollHandler { - queues: Vec>>, + queue: Queue>, random_file: File, interrupt_cb: Arc, queue_evt: EventFd, @@ -46,7 +46,7 @@ struct RngEpollHandler { impl RngEpollHandler { fn process_queue(&mut self) -> bool { - let queue = &mut self.queues[0]; + let queue = &mut self.queue; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; @@ -219,10 +219,9 @@ impl VirtioDevice for Rng { &mut self, _mem: GuestMemoryAtomic, interrupt_cb: Arc, - queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let (kill_evt, pause_evt) = self.common.dup_eventfds(); if let Some(file) = self.random_file.as_ref() { @@ -230,11 +229,14 @@ impl VirtioDevice for Rng { error!("failed cloning rng source: {}", e); ActivateError::BadActivate })?; + + let (_, queue, queue_evt) = queues.remove(0); + let mut handler = RngEpollHandler { - queues, + queue, random_file, interrupt_cb, - queue_evt: queue_evts.remove(0), + queue_evt, kill_evt, pause_evt, access_platform: self.common.access_platform.clone(), diff --git a/virtio-devices/src/transport/pci_common_config.rs b/virtio-devices/src/transport/pci_common_config.rs index 889778582..ef30ee777 100644 --- a/virtio-devices/src/transport/pci_common_config.rs +++ b/virtio-devices/src/transport/pci_common_config.rs @@ -385,8 +385,7 @@ mod tests { &mut self, _mem: GuestMemoryAtomic, _interrupt_evt: Arc, - _queues: Vec>>, - _queue_evts: Vec, + _queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { Ok(()) } diff --git a/virtio-devices/src/transport/pci_device.rs b/virtio-devices/src/transport/pci_device.rs index 8d460dd7a..744bf8f49 100644 --- a/virtio-devices/src/transport/pci_device.rs +++ b/virtio-devices/src/transport/pci_device.rs @@ -292,8 +292,8 @@ pub struct VirtioPciDeviceActivator { memory: Option>, device: Arc>, device_activated: Arc, - queues: Option>>>, - queue_evts: Option>, + #[allow(clippy::type_complexity)] + queues: Option>, EventFd)>>, barrier: Option>, id: String, } @@ -304,7 +304,6 @@ impl VirtioPciDeviceActivator { self.memory.take().unwrap(), self.interrupt.take().unwrap(), self.queues.take().unwrap(), - self.queue_evts.take().unwrap(), )?; self.device_activated.store(true, Ordering::SeqCst); @@ -700,7 +699,6 @@ impl VirtioPciDevice { fn prepare_activator(&mut self, barrier: Option>) -> VirtioPciDeviceActivator { let mut queues = Vec::new(); - let mut queue_evts = Vec::new(); for (queue_index, queue) in self.queues.iter().enumerate() { if !queue.state.ready { @@ -711,8 +709,11 @@ impl VirtioPciDevice { error!("Queue {} is not valid", queue_index); } - queues.push(vm_virtio::clone_queue(queue)); - queue_evts.push(self.queue_evts[queue_index].try_clone().unwrap()); + queues.push(( + queue_index, + vm_virtio::clone_queue(queue), + self.queue_evts[queue_index].try_clone().unwrap(), + )); } VirtioPciDeviceActivator { @@ -721,7 +722,6 @@ impl VirtioPciDevice { device: self.device.clone(), queues: Some(queues), device_activated: self.device_activated.clone(), - queue_evts: Some(queue_evts), barrier, id: self.id.clone(), } diff --git a/virtio-devices/src/vdpa.rs b/virtio-devices/src/vdpa.rs index 58e78ba6f..47046b364 100644 --- a/virtio-devices/src/vdpa.rs +++ b/virtio-devices/src/vdpa.rs @@ -145,8 +145,7 @@ impl Vdpa { &mut self, _mem: &GuestMemoryMmap, virtio_interrupt: &Arc, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, ) -> Result<()> { self.vhost .set_features(self.common.acked_features) @@ -155,11 +154,11 @@ impl Vdpa { .set_backend_features(self.backend_features) .map_err(Error::SetBackendFeatures)?; - for (queue_index, queue) in queues.iter().enumerate() { + for (queue_index, queue, queue_evt) in queues.iter() { let queue_max_size = queue.max_size(); let queue_size = queue.state.size; self.vhost - .set_vring_num(queue_index, queue_size) + .set_vring_num(*queue_index, queue_size) .map_err(Error::SetVringNum)?; let config_data = VringConfigData { @@ -194,11 +193,11 @@ impl Vdpa { }; self.vhost - .set_vring_addr(queue_index, &config_data) + .set_vring_addr(*queue_index, &config_data) .map_err(Error::SetVringAddr)?; self.vhost .set_vring_base( - queue_index, + *queue_index, queue .avail_idx(Ordering::Acquire) .map_err(Error::GetAvailableIndex)? @@ -207,15 +206,15 @@ impl Vdpa { .map_err(Error::SetVringBase)?; if let Some(eventfd) = - virtio_interrupt.notifier(VirtioInterruptType::Queue(queue_index as u16)) + virtio_interrupt.notifier(VirtioInterruptType::Queue(*queue_index as u16)) { self.vhost - .set_vring_call(queue_index, &eventfd) + .set_vring_call(*queue_index, &eventfd) .map_err(Error::SetVringCall)?; } self.vhost - .set_vring_kick(queue_index, &queue_evts[queue_index]) + .set_vring_kick(*queue_index, queue_evt) .map_err(Error::SetVringKick)?; } @@ -297,10 +296,9 @@ impl VirtioDevice for Vdpa { &mut self, mem: GuestMemoryAtomic, virtio_interrupt: Arc, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.activate_vdpa(&mem.memory(), &virtio_interrupt, queues, queue_evts) + self.activate_vdpa(&mem.memory(), &virtio_interrupt, queues) .map_err(ActivateError::ActivateVdpa)?; // Store the virtio interrupt handler as we need to return it on reset diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index f24b2ff9c..5a0798a99 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -292,10 +292,9 @@ impl VirtioDevice for Blk { &mut self, mem: GuestMemoryAtomic, interrupt_cb: Arc, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; self.guest_memory = Some(mem.clone()); let slave_req_handler: Option> = None; @@ -307,7 +306,6 @@ impl VirtioDevice for Blk { let mut handler = self.vu_common.activate( mem, queues, - queue_evts, interrupt_cb, self.common.acked_features, slave_req_handler, diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index 2ceddaddb..9cd0e3a83 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -504,10 +504,9 @@ impl VirtioDevice for Fs { &mut self, mem: GuestMemoryAtomic, interrupt_cb: Arc, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; self.guest_memory = Some(mem.clone()); // Initialize slave communication. @@ -547,7 +546,6 @@ impl VirtioDevice for Fs { let mut handler = self.vu_common.activate( mem, queues, - queue_evts, interrupt_cb, self.common.acked_features, slave_req_handler, diff --git a/virtio-devices/src/vhost_user/mod.rs b/virtio-devices/src/vhost_user/mod.rs index e3aac2dd1..5c29369ba 100644 --- a/virtio-devices/src/vhost_user/mod.rs +++ b/virtio-devices/src/vhost_user/mod.rs @@ -167,8 +167,7 @@ pub struct VhostUserEpollHandler { pub mem: GuestMemoryAtomic, pub kill_evt: EventFd, pub pause_evt: EventFd, - pub queues: Vec>>, - pub queue_evts: Vec, + pub queues: Vec<(usize, Queue>, EventFd)>, pub virtio_interrupt: Arc, pub acked_features: u64, pub acked_protocol_features: u64, @@ -224,10 +223,9 @@ impl VhostUserEpollHandler { vhost_user .reinitialize_vhost_user( self.mem.memory().deref(), - self.queues.iter().map(vm_virtio::clone_queue).collect(), - self.queue_evts + self.queues .iter() - .map(|q| q.try_clone().unwrap()) + .map(|(i, q, e)| (*i, vm_virtio::clone_queue(q), e.try_clone().unwrap())) .collect(), &self.virtio_interrupt, self.acked_features, @@ -299,8 +297,7 @@ impl VhostUserCommon { pub fn activate( &mut self, mem: GuestMemoryAtomic, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, interrupt_cb: Arc, acked_features: u64, slave_req_handler: Option>, @@ -324,8 +321,10 @@ impl VhostUserCommon { .unwrap() .setup_vhost_user( &mem.memory(), - queues.iter().map(vm_virtio::clone_queue).collect(), - queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(), + queues + .iter() + .map(|(i, q, e)| (*i, vm_virtio::clone_queue(q), e.try_clone().unwrap())) + .collect(), &interrupt_cb, acked_features, &slave_req_handler, @@ -339,7 +338,6 @@ impl VhostUserCommon { kill_evt, pause_evt, queues, - queue_evts, virtio_interrupt: interrupt_cb, acked_features, acked_protocol_features: self.acked_protocol_features, diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index fb90edda1..1619c7bfe 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -272,18 +272,16 @@ impl VirtioDevice for Net { &mut self, mem: GuestMemoryAtomic, interrupt_cb: Arc, - mut queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; self.guest_memory = Some(mem.clone()); let num_queues = queues.len(); let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into()); if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && num_queues % 2 != 0 { let ctrl_queue_index = num_queues - 1; - let mut ctrl_queue = queues.remove(ctrl_queue_index); - let ctrl_queue_evt = queue_evts.remove(ctrl_queue_index); + let (_, mut ctrl_queue, ctrl_queue_evt) = queues.remove(ctrl_queue_index); ctrl_queue.set_event_idx(event_idx); @@ -336,7 +334,6 @@ impl VirtioDevice for Net { let mut handler = self.vu_common.activate( mem, queues, - queue_evts, interrupt_cb, backend_acked_features, slave_req_handler, diff --git a/virtio-devices/src/vhost_user/vu_common_ctrl.rs b/virtio-devices/src/vhost_user/vu_common_ctrl.rs index 53d273c67..491a33a46 100644 --- a/virtio-devices/src/vhost_user/vu_common_ctrl.rs +++ b/virtio-devices/src/vhost_user/vu_common_ctrl.rs @@ -151,8 +151,7 @@ impl VhostUserHandle { pub fn setup_vhost_user( &mut self, mem: &GuestMemoryMmap, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, virtio_interrupt: &Arc, acked_features: u64, slave_req_handler: &Option>, @@ -171,9 +170,9 @@ impl VhostUserHandle { // Send set_vring_num here, since it could tell backends, like SPDK, // how many virt queues to be handled, which backend required to know // at early stage. - for (queue_index, queue) in queues.iter().enumerate() { + for (queue_index, queue, _) in queues.iter() { self.vu - .set_vring_num(queue_index, queue.state.size) + .set_vring_num(*queue_index, queue.state.size) .map_err(Error::VhostUserSetVringNum)?; } @@ -184,7 +183,7 @@ impl VhostUserHandle { mmap_size: 0, mmap_offset: 0, num_queues: queues.len() as u16, - queue_size: queues[0].state.size, + queue_size: queues[0].1.state.size, }; let (info, fd) = self .vu @@ -202,7 +201,7 @@ impl VhostUserHandle { let num_queues = queues.len() as usize; let mut vrings_info = Vec::new(); - for (queue_index, queue) in queues.into_iter().enumerate() { + for (queue_index, queue, queue_evt) in queues.iter() { let actual_size: usize = queue.state.size.try_into().unwrap(); let config_data = VringConfigData { @@ -240,11 +239,11 @@ impl VhostUserHandle { }); self.vu - .set_vring_addr(queue_index, &config_data) + .set_vring_addr(*queue_index, &config_data) .map_err(Error::VhostUserSetVringAddr)?; self.vu .set_vring_base( - queue_index, + *queue_index, queue .avail_idx(Ordering::Acquire) .map_err(Error::GetAvailableIndex)? @@ -253,15 +252,15 @@ impl VhostUserHandle { .map_err(Error::VhostUserSetVringBase)?; if let Some(eventfd) = - virtio_interrupt.notifier(VirtioInterruptType::Queue(queue_index as u16)) + virtio_interrupt.notifier(VirtioInterruptType::Queue(*queue_index as u16)) { self.vu - .set_vring_call(queue_index, &eventfd) + .set_vring_call(*queue_index, &eventfd) .map_err(Error::VhostUserSetVringCall)?; } self.vu - .set_vring_kick(queue_index, &queue_evts[queue_index]) + .set_vring_kick(*queue_index, queue_evt) .map_err(Error::VhostUserSetVringKick)?; } @@ -326,8 +325,7 @@ impl VhostUserHandle { pub fn reinitialize_vhost_user( &mut self, mem: &GuestMemoryMmap, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, virtio_interrupt: &Arc, acked_features: u64, acked_protocol_features: u64, @@ -339,7 +337,6 @@ impl VhostUserHandle { self.setup_vhost_user( mem, queues, - queue_evts, virtio_interrupt, acked_features, slave_req_handler, diff --git a/virtio-devices/src/vsock/device.rs b/virtio-devices/src/vsock/device.rs index 16d863d88..4156fad64 100644 --- a/virtio-devices/src/vsock/device.rs +++ b/virtio-devices/src/vsock/device.rs @@ -432,15 +432,21 @@ where &mut self, mem: GuestMemoryAtomic, interrupt_cb: Arc, - queues: Vec>>, - queue_evts: Vec, + queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let mut virtqueues = Vec::new(); + let mut queue_evts = Vec::new(); + for (_, queue, queue_evt) in queues { + virtqueues.push(queue); + queue_evts.push(queue_evt); + } + let mut handler = VsockEpollHandler { mem, - queues, + queues: virtqueues, queue_evts, kill_evt, pause_evt, @@ -591,7 +597,6 @@ mod tests { GuestMemoryAtomic::new(ctx.mem.clone()), Arc::new(NoopVirtioInterrupt {}), Vec::new(), - Vec::new(), ); match bad_activate { Err(ActivateError::BadActivate) => (), @@ -606,14 +611,21 @@ mod tests { memory.clone(), Arc::new(NoopVirtioInterrupt {}), vec![ - Queue::new(memory.clone(), 256), - Queue::new(memory.clone(), 256), - Queue::new(memory, 256), - ], - vec![ - EventFd::new(EFD_NONBLOCK).unwrap(), - EventFd::new(EFD_NONBLOCK).unwrap(), - EventFd::new(EFD_NONBLOCK).unwrap(), + ( + 0, + Queue::new(memory.clone(), 256), + EventFd::new(EFD_NONBLOCK).unwrap(), + ), + ( + 1, + Queue::new(memory.clone(), 256), + EventFd::new(EFD_NONBLOCK).unwrap(), + ), + ( + 2, + Queue::new(memory, 256), + EventFd::new(EFD_NONBLOCK).unwrap(), + ), ], ) .unwrap(); diff --git a/virtio-devices/src/watchdog.rs b/virtio-devices/src/watchdog.rs index fa6bbc115..6627b31d4 100644 --- a/virtio-devices/src/watchdog.rs +++ b/virtio-devices/src/watchdog.rs @@ -47,7 +47,7 @@ const WATCHDOG_TIMER_INTERVAL: i64 = 15; const WATCHDOG_TIMEOUT: u64 = WATCHDOG_TIMER_INTERVAL as u64 + 5; struct WatchdogEpollHandler { - queues: Vec>>, + queue: Queue>, interrupt_cb: Arc, queue_evt: EventFd, kill_evt: EventFd, @@ -61,7 +61,7 @@ impl WatchdogEpollHandler { // The main queue is very simple - the driver "pings" the device by passing it a (write-only) // descriptor. In response the device writes a 1 into the descriptor and returns it to the driver fn process_queue(&mut self) -> bool { - let queue = &mut self.queues[0]; + let queue = &mut self.queue; let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; for mut desc_chain in queue.iter().unwrap() { @@ -291,10 +291,9 @@ impl VirtioDevice for Watchdog { &mut self, _mem: GuestMemoryAtomic, interrupt_cb: Arc, - queues: Vec>>, - mut queue_evts: Vec, + mut queues: Vec<(usize, Queue>, EventFd)>, ) -> ActivateResult { - self.common.activate(&queues, &queue_evts, &interrupt_cb)?; + self.common.activate(&queues, &interrupt_cb)?; let (kill_evt, pause_evt) = self.common.dup_eventfds(); let reset_evt = self.reset_evt.try_clone().map_err(|e| { @@ -307,10 +306,12 @@ impl VirtioDevice for Watchdog { ActivateError::BadActivate })?; + let (_, queue, queue_evt) = queues.remove(0); + let mut handler = WatchdogEpollHandler { - queues, + queue, interrupt_cb, - queue_evt: queue_evts.remove(0), + queue_evt, kill_evt, pause_evt, timer,