diff --git a/net_util/src/ctrl_queue.rs b/net_util/src/ctrl_queue.rs index e3d8300ba..76477d565 100644 --- a/net_util/src/ctrl_queue.rs +++ b/net_util/src/ctrl_queue.rs @@ -62,7 +62,6 @@ impl CtrlQueue { queue: &mut Queue, access_platform: Option<&Arc>, ) -> Result<()> { - let mut used_desc_heads = Vec::new(); while let Some(mut desc_chain) = queue.pop_descriptor_chain(mem) { let ctrl_desc = desc_chain.next().ok_or(Error::NoControlHeaderDescriptor)?; @@ -139,7 +138,10 @@ impl CtrlQueue { ) .map_err(Error::GuestMemory)?; let len = ctrl_desc.len() + data_desc.len() + status_desc.len(); - used_desc_heads.push((desc_chain.head_index(), len)); + + queue + .add_used(desc_chain.memory(), desc_chain.head_index(), len) + .map_err(Error::QueueAddUsed)?; if !queue .enable_notification(mem) @@ -149,12 +151,6 @@ impl CtrlQueue { } } - for (desc_index, len) in used_desc_heads.iter() { - queue - .add_used(mem, *desc_index, *len) - .map_err(Error::QueueAddUsed)?; - } - Ok(()) } } diff --git a/net_util/src/queue_pair.rs b/net_util/src/queue_pair.rs index 825adcc3f..37a3b2d21 100644 --- a/net_util/src/queue_pair.rs +++ b/net_util/src/queue_pair.rs @@ -120,7 +120,7 @@ impl TxVirtio { } queue - .add_used(mem, desc_chain.head_index(), len) + .add_used(desc_chain.memory(), desc_chain.head_index(), len) .map_err(NetQueuePairError::QueueAddUsed)?; if !queue @@ -262,7 +262,7 @@ impl RxVirtio { } queue - .add_used(mem, desc_chain.head_index(), len) + .add_used(desc_chain.memory(), desc_chain.head_index(), len) .map_err(NetQueuePairError::QueueAddUsed)?; if !queue diff --git a/vhost_user_block/src/lib.rs b/vhost_user_block/src/lib.rs index 9bf565cdf..059d74b20 100644 --- a/vhost_user_block/src/lib.rs +++ b/vhost_user_block/src/lib.rs @@ -124,7 +124,7 @@ impl VhostUserBlkThread { &mut self, vring: &mut RwLockWriteGuard>>, ) -> bool { - let mut used_desc_heads = Vec::new(); + let mut used_descs = false; while let Some(mut desc_chain) = vring .get_queue_mut() @@ -162,37 +162,35 @@ impl VhostUserBlkThread { } } - used_desc_heads.push((desc_chain.head_index(), len)); + vring + .get_queue_mut() + .add_used(desc_chain.memory(), desc_chain.head_index(), len) + .unwrap(); + used_descs = true; } - let mem = self.mem.memory(); let mut needs_signalling = false; - for (desc_head, len) in used_desc_heads.iter() { - if self.event_idx { - let queue = vring.get_queue_mut(); - if queue.add_used(mem.deref(), *desc_head, *len).is_ok() { - if queue.needs_notification(mem.deref()).unwrap() { - debug!("signalling queue"); - needs_signalling = true; - } else { - debug!("omitting signal (event_idx)"); - } - } - } else { + if self.event_idx { + if vring + .get_queue_mut() + .needs_notification(self.mem.memory().deref()) + .unwrap() + { debug!("signalling queue"); - vring - .get_queue_mut() - .add_used(mem.deref(), *desc_head, *len) - .unwrap(); needs_signalling = true; + } else { + debug!("omitting signal (event_idx)"); } + } else { + debug!("signalling queue"); + needs_signalling = true; } if needs_signalling { vring.signal_used_queue().unwrap(); } - !used_desc_heads.is_empty() + used_descs } } diff --git a/virtio-devices/src/balloon.rs b/virtio-devices/src/balloon.rs index d4b747e43..964ebc46c 100644 --- a/virtio-devices/src/balloon.rs +++ b/virtio-devices/src/balloon.rs @@ -22,7 +22,6 @@ use libc::EFD_NONBLOCK; use seccompiler::SeccompAction; use std::io; use std::mem::size_of; -use std::ops::Deref; use std::os::unix::io::AsRawFd; use std::result; use std::sync::{ @@ -31,7 +30,7 @@ use std::sync::{ }; use versionize::{VersionMap, Versionize, VersionizeResult}; use versionize_derive::Versionize; -use virtio_queue::{Queue, QueueOwnedT, QueueT}; +use virtio_queue::{Queue, QueueT}; use vm_memory::{ Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestMemoryError, GuestMemoryRegion, @@ -227,34 +226,13 @@ impl BalloonEpollHandler { Self::advise_memory_range(memory, range_base, range_len, libc::MADV_DONTNEED) } - fn notify_queue( - &mut self, - queue_index: usize, - used_descs: Vec<(u16, u32)>, - ) -> result::Result<(), Error> { - let mem = self.mem.memory(); - for (desc_index, len) in used_descs.iter() { - self.queues[queue_index] - .add_used(mem.deref(), *desc_index, *len) - .map_err(Error::QueueAddUsed)?; - } - - if !used_descs.is_empty() { - self.signal(VirtioInterruptType::Queue(queue_index as u16))?; - } - - Ok(()) - } - fn process_queue(&mut self, queue_index: usize) -> result::Result<(), Error> { - let mut used_descs = Vec::new(); + let mut used_descs = false; while let Some(mut desc_chain) = self.queues[queue_index].pop_descriptor_chain(self.mem.memory()) { let desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?; - used_descs.push((desc_chain.head_index(), desc.len())); - let data_chunk_size = size_of::(); // The head contains the request type which MUST be readable. @@ -294,18 +272,24 @@ impl BalloonEpollHandler { _ => return Err(Error::InvalidQueueIndex(queue_index)), } } + + self.queues[queue_index] + .add_used(desc_chain.memory(), desc_chain.head_index(), desc.len()) + .map_err(Error::QueueAddUsed)?; + used_descs = true; } - self.notify_queue(queue_index, used_descs) + if used_descs { + self.signal(VirtioInterruptType::Queue(queue_index as u16)) + } else { + Ok(()) + } } fn process_reporting_queue(&mut self, queue_index: usize) -> result::Result<(), Error> { - let mem = self.mem.memory(); - let mut used_descs = Vec::new(); - - for mut desc_chain in self.queues[queue_index] - .iter(mem) - .map_err(Error::QueueIterator)? + let mut used_descs = false; + while let Some(mut desc_chain) = + self.queues[queue_index].pop_descriptor_chain(self.mem.memory()) { let mut descs_len = 0; while let Some(desc) = desc_chain.next() { @@ -313,10 +297,17 @@ impl BalloonEpollHandler { Self::release_memory_range(desc_chain.memory(), desc.addr(), desc.len() as usize)?; } - used_descs.push((desc_chain.head_index(), descs_len)); + self.queues[queue_index] + .add_used(desc_chain.memory(), desc_chain.head_index(), descs_len) + .map_err(Error::QueueAddUsed)?; + used_descs = true; } - self.notify_queue(queue_index, used_descs) + if used_descs { + self.signal(VirtioInterruptType::Queue(queue_index as u16)) + } else { + Ok(()) + } } fn run( diff --git a/virtio-devices/src/block.rs b/virtio-devices/src/block.rs index 7e4f2cda3..fc3b74de6 100644 --- a/virtio-devices/src/block.rs +++ b/virtio-devices/src/block.rs @@ -105,8 +105,7 @@ impl BlockEpollHandler { fn process_queue_submit(&mut self) -> Result { let queue = &mut self.queue; - let mut used_desc_heads = Vec::new(); - let mut used_count = 0; + let mut used_descs = false; while let Some(mut desc_chain) = queue.pop_descriptor_chain(self.mem.memory()) { let mut request = Request::parse(&mut desc_chain, self.access_platform.as_ref()) @@ -166,26 +165,20 @@ impl BlockEpollHandler { // If no asynchronous operation has been submitted, we can // simply return the used descriptor. - used_desc_heads.push((desc_chain.head_index(), 0)); - used_count += 1; + queue + .add_used(desc_chain.memory(), desc_chain.head_index(), 0) + .map_err(Error::QueueAddUsed)?; + used_descs = true; } } - let mem = self.mem.memory(); - for &(desc_index, len) in used_desc_heads.iter() { - queue - .add_used(mem.deref(), desc_index, len) - .map_err(Error::QueueAddUsed)?; - } - - Ok(used_count > 0) + Ok(used_descs) } fn process_queue_complete(&mut self) -> Result { let queue = &mut self.queue; - let mut used_desc_heads = Vec::new(); - let mut used_count = 0; + let mut used_descs = false; let mem = self.mem.memory(); let mut read_bytes = Wrapping(0); let mut write_bytes = Wrapping(0); @@ -234,14 +227,10 @@ impl BlockEpollHandler { // checked that the status_addr was valid. mem.write_obj(status, request.status_addr).unwrap(); - used_desc_heads.push((desc_index as u16, len)); - used_count += 1; - } - - for &(desc_index, len) in used_desc_heads.iter() { queue - .add_used(mem.deref(), desc_index, len) + .add_used(mem.deref(), desc_index as u16, len) .map_err(Error::QueueAddUsed)?; + used_descs = true; } self.counters @@ -258,7 +247,7 @@ impl BlockEpollHandler { .read_ops .fetch_add(read_ops.0, Ordering::AcqRel); - Ok(used_count > 0) + Ok(used_descs) } fn signal_used_queue(&self) -> result::Result<(), DeviceError> { diff --git a/virtio-devices/src/console.rs b/virtio-devices/src/console.rs index 345a74e0c..38f4358e7 100644 --- a/virtio-devices/src/console.rs +++ b/virtio-devices/src/console.rs @@ -18,7 +18,6 @@ use std::collections::VecDeque; use std::fs::File; use std::io; use std::io::{Read, Write}; -use std::ops::Deref; use std::os::unix::io::AsRawFd; use std::result; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; @@ -137,8 +136,7 @@ impl ConsoleEpollHandler { fn process_input_queue(&mut self) -> bool { let mut in_buffer = self.in_buffer.lock().unwrap(); let recv_queue = &mut self.queues[0]; //receiveq - let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; - let mut used_count = 0; + let mut used_descs = false; if in_buffer.is_empty() { return false; @@ -159,20 +157,17 @@ impl ConsoleEpollHandler { break; } - used_desc_heads[used_count] = (desc_chain.head_index(), len); - used_count += 1; + recv_queue + .add_used(desc_chain.memory(), desc_chain.head_index(), len) + .unwrap(); + used_descs = true; if in_buffer.is_empty() { break; } } - let mem = self.mem.memory(); - for &(desc_index, len) in &used_desc_heads[..used_count] { - recv_queue.add_used(mem.deref(), desc_index, len).unwrap(); - } - - used_count > 0 + used_descs } /* @@ -184,8 +179,7 @@ impl ConsoleEpollHandler { */ fn process_output_queue(&mut self) -> bool { let trans_queue = &mut self.queues[1]; //transmitq - let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; - let mut used_count = 0; + let mut used_descs = false; while let Some(mut desc_chain) = trans_queue.pop_descriptor_chain(self.mem.memory()) { let desc = desc_chain.next().unwrap(); @@ -198,15 +192,13 @@ impl ConsoleEpollHandler { ); let _ = out.flush(); } - used_desc_heads[used_count] = (desc_chain.head_index(), desc.len()); - used_count += 1; + trans_queue + .add_used(desc_chain.memory(), desc_chain.head_index(), desc.len()) + .unwrap(); + used_descs = true; } - let mem = self.mem.memory(); - for &(desc_index, len) in &used_desc_heads[..used_count] { - trans_queue.add_used(mem.deref(), desc_index, len).unwrap(); - } - used_count > 0 + used_descs } fn signal_used_queue(&self, queue_index: u16) -> result::Result<(), DeviceError> { diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index ea9477719..275c7e844 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -17,7 +17,6 @@ use std::fmt::{self, Display}; use std::io; use std::mem::size_of; use std::ops::Bound::Included; -use std::ops::Deref; use std::os::unix::io::AsRawFd; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; @@ -674,8 +673,7 @@ struct IommuEpollHandler { impl IommuEpollHandler { fn request_queue(&mut self) -> bool { - let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; - let mut used_count = 0; + let mut used_descs = false; while let Some(mut desc_chain) = self.queues[0].pop_descriptor_chain(self.mem.memory()) { let len = match Request::parse( &mut desc_chain, @@ -690,17 +688,13 @@ impl IommuEpollHandler { } }; - used_desc_heads[used_count] = (desc_chain.head_index(), len); - used_count += 1; + self.queues[0] + .add_used(desc_chain.memory(), desc_chain.head_index(), len) + .unwrap(); + used_descs = true; } - let mem = self.mem.memory(); - for &(desc_index, len) in &used_desc_heads[..used_count] { - self.queues[0] - .add_used(mem.deref(), desc_index, len) - .unwrap(); - } - used_count > 0 + used_descs } fn event_queue(&mut self) -> bool { diff --git a/virtio-devices/src/mem.rs b/virtio-devices/src/mem.rs index c2f45aa19..1974ba0e6 100644 --- a/virtio-devices/src/mem.rs +++ b/virtio-devices/src/mem.rs @@ -27,7 +27,6 @@ use seccompiler::SeccompAction; use std::collections::BTreeMap; use std::io; use std::mem::size_of; -use std::ops::Deref; use std::os::unix::io::{AsRawFd, RawFd}; use std::result; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; @@ -665,20 +664,10 @@ impl MemEpollHandler { } fn process_queue(&mut self) -> bool { - let mut request_list = Vec::new(); - let mut used_count = 0; + let mut used_descs = false; while let Some(mut desc_chain) = self.queue.pop_descriptor_chain(self.mem.memory()) { - request_list.push(( - desc_chain.head_index(), - Request::parse(&mut desc_chain), - desc_chain.memory().clone(), - )); - } - - let mem = self.mem.memory(); - for (head_index, request, memory) in request_list { - let len = match request { + let len = match Request::parse(&mut desc_chain) { Err(e) => { error!("failed parse VirtioMemReq: {:?}", e); 0 @@ -687,21 +676,21 @@ impl MemEpollHandler { VIRTIO_MEM_REQ_PLUG => { let resp_type = self.state_change_request(r.req.addr, r.req.nb_blocks, true); - r.send_response(&memory, resp_type, 0u16) + r.send_response(desc_chain.memory(), resp_type, 0u16) } VIRTIO_MEM_REQ_UNPLUG => { let resp_type = self.state_change_request(r.req.addr, r.req.nb_blocks, false); - r.send_response(&memory, resp_type, 0u16) + r.send_response(desc_chain.memory(), resp_type, 0u16) } VIRTIO_MEM_REQ_UNPLUG_ALL => { let resp_type = self.unplug_all(); - r.send_response(&memory, resp_type, 0u16) + r.send_response(desc_chain.memory(), resp_type, 0u16) } VIRTIO_MEM_REQ_STATE => { let (resp_type, resp_state) = self.state_request(r.req.addr, r.req.nb_blocks); - r.send_response(&memory, resp_type, resp_state) + r.send_response(desc_chain.memory(), resp_type, resp_state) } _ => { error!("VirtioMemReq unknown request type {:?}", r.req.req_type); @@ -710,11 +699,13 @@ impl MemEpollHandler { }, }; - self.queue.add_used(mem.deref(), head_index, len).unwrap(); - used_count += 1; + self.queue + .add_used(desc_chain.memory(), desc_chain.head_index(), len) + .unwrap(); + used_descs = true; } - used_count > 0 + used_descs } fn run( diff --git a/virtio-devices/src/pmem.rs b/virtio-devices/src/pmem.rs index 64f923fad..e52fbddf4 100644 --- a/virtio-devices/src/pmem.rs +++ b/virtio-devices/src/pmem.rs @@ -21,7 +21,6 @@ use std::fmt::{self, Display}; use std::fs::File; use std::io; use std::mem::size_of; -use std::ops::Deref; use std::os::unix::io::AsRawFd; use std::result; use std::sync::atomic::AtomicBool; @@ -178,8 +177,7 @@ struct PmemEpollHandler { impl PmemEpollHandler { fn process_queue(&mut self) -> bool { - let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; - let mut used_count = 0; + let mut used_descs = false; while let Some(mut desc_chain) = self.queue.pop_descriptor_chain(self.mem.memory()) { let len = match Request::parse(&mut desc_chain, self.access_platform.as_ref()) { Ok(ref req) if (req.type_ == RequestType::Flush) => { @@ -211,15 +209,13 @@ impl PmemEpollHandler { } }; - used_desc_heads[used_count] = (desc_chain.head_index(), len); - used_count += 1; + self.queue + .add_used(desc_chain.memory(), desc_chain.head_index(), len) + .unwrap(); + used_descs = true; } - let mem = self.mem.memory(); - for &(desc_index, len) in &used_desc_heads[..used_count] { - self.queue.add_used(mem.deref(), desc_index, len).unwrap(); - } - used_count > 0 + used_descs } fn signal_used_queue(&self) -> result::Result<(), DeviceError> { diff --git a/virtio-devices/src/rng.rs b/virtio-devices/src/rng.rs index 9d7db1665..50fdad92b 100644 --- a/virtio-devices/src/rng.rs +++ b/virtio-devices/src/rng.rs @@ -15,7 +15,6 @@ use crate::{VirtioInterrupt, VirtioInterruptType}; use seccompiler::SeccompAction; use std::fs::File; use std::io; -use std::ops::Deref; use std::os::unix::io::AsRawFd; use std::result; use std::sync::atomic::AtomicBool; @@ -50,8 +49,7 @@ impl RngEpollHandler { fn process_queue(&mut self) -> bool { let queue = &mut self.queue; - let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; - let mut used_count = 0; + let mut used_descs = false; while let Some(mut desc_chain) = queue.pop_descriptor_chain(self.mem.memory()) { let desc = desc_chain.next().unwrap(); let mut len = 0; @@ -73,15 +71,13 @@ impl RngEpollHandler { } } - used_desc_heads[used_count] = (desc_chain.head_index(), len); - used_count += 1; + queue + .add_used(desc_chain.memory(), desc_chain.head_index(), len) + .unwrap(); + used_descs = true; } - let mem = self.mem.memory(); - for &(desc_index, len) in &used_desc_heads[..used_count] { - queue.add_used(mem.deref(), desc_index, len).unwrap(); - } - used_count > 0 + used_descs } fn signal_used_queue(&self) -> result::Result<(), DeviceError> { diff --git a/virtio-devices/src/vsock/device.rs b/virtio-devices/src/vsock/device.rs index c8c4b5f4b..280c3a5c2 100644 --- a/virtio-devices/src/vsock/device.rs +++ b/virtio-devices/src/vsock/device.rs @@ -40,7 +40,6 @@ use crate::{ use byteorder::{ByteOrder, LittleEndian}; use seccompiler::SeccompAction; use std::io; -use std::ops::Deref; use std::os::unix::io::AsRawFd; use std::path::PathBuf; use std::result; @@ -125,8 +124,7 @@ where fn process_rx(&mut self) -> result::Result<(), DeviceError> { debug!("vsock: epoll_handler::process_rx()"); - let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; - let mut used_count = 0; + let mut used_descs = false; while let Some(mut desc_chain) = self.queues[0].pop_descriptor_chain(self.mem.memory()) { let used_len = match VsockPacket::from_rx_virtq_head( @@ -149,18 +147,13 @@ where } }; - used_desc_heads[used_count] = (desc_chain.head_index(), used_len); - used_count += 1; - } - - let mem = self.mem.memory(); - for &(desc_index, len) in &used_desc_heads[..used_count] { self.queues[0] - .add_used(mem.deref(), desc_index, len) + .add_used(desc_chain.memory(), desc_chain.head_index(), used_len) .map_err(DeviceError::QueueAddUsed)?; + used_descs = true; } - if used_count > 0 { + if used_descs { self.signal_used_queue(0) } else { Ok(()) @@ -173,8 +166,7 @@ where fn process_tx(&mut self) -> result::Result<(), DeviceError> { debug!("vsock: epoll_handler::process_tx()"); - let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; - let mut used_count = 0; + let mut used_descs = false; while let Some(mut desc_chain) = self.queues[1].pop_descriptor_chain(self.mem.memory()) { let pkt = match VsockPacket::from_tx_virtq_head( @@ -184,8 +176,10 @@ where Ok(pkt) => pkt, Err(e) => { error!("vsock: error reading TX packet: {:?}", e); - used_desc_heads[used_count] = (desc_chain.head_index(), 0); - used_count += 1; + self.queues[1] + .add_used(desc_chain.memory(), desc_chain.head_index(), 0) + .map_err(DeviceError::QueueAddUsed)?; + used_descs = true; continue; } }; @@ -195,18 +189,13 @@ where break; } - used_desc_heads[used_count] = (desc_chain.head_index(), 0); - used_count += 1; - } - - let mem = self.mem.memory(); - for &(desc_index, len) in &used_desc_heads[..used_count] { self.queues[1] - .add_used(mem.deref(), desc_index, len) + .add_used(desc_chain.memory(), desc_chain.head_index(), 0) .map_err(DeviceError::QueueAddUsed)?; + used_descs = true; } - if used_count > 0 { + if used_descs { self.signal_used_queue(1) } else { Ok(())