mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: Improve queue handling with pop_descriptor_chain()
Using pop_descriptor_chain() is much more appropriate than iter() since it recreates the iterator every time, avoiding the queue to be borrowed and allowing the virtio-net implementation to match all the other ones. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
committed by
Rob Bradford
parent
a423bf13ad
commit
87f57f7c1e
@@ -247,11 +247,9 @@ impl BalloonEpollHandler {
|
||||
}
|
||||
|
||||
fn process_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)?
|
||||
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)?;
|
||||
|
||||
|
||||
@@ -108,10 +108,7 @@ impl BlockEpollHandler {
|
||||
let mut used_desc_heads = Vec::new();
|
||||
let mut used_count = 0;
|
||||
|
||||
let mut avail_iter = queue
|
||||
.iter(self.mem.memory())
|
||||
.map_err(Error::QueueIterator)?;
|
||||
for mut desc_chain in &mut avail_iter {
|
||||
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())
|
||||
.map_err(Error::RequestParsing)?;
|
||||
|
||||
@@ -121,7 +118,7 @@ impl BlockEpollHandler {
|
||||
if !rate_limiter.consume(1, TokenType::Ops) {
|
||||
// Stop processing the queue and return this descriptor chain to the
|
||||
// avail ring, for later processing.
|
||||
avail_iter.go_to_previous_position();
|
||||
queue.go_to_previous_position();
|
||||
break;
|
||||
}
|
||||
// Exercise the rate limiter only if this request is of data transfer type.
|
||||
@@ -140,7 +137,7 @@ impl BlockEpollHandler {
|
||||
rate_limiter.manual_replenish(1, TokenType::Ops);
|
||||
// Stop processing the queue and return this descriptor chain to the
|
||||
// avail ring, for later processing.
|
||||
avail_iter.go_to_previous_position();
|
||||
queue.go_to_previous_position();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -144,8 +144,7 @@ impl ConsoleEpollHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut avail_iter = recv_queue.iter(self.mem.memory()).unwrap();
|
||||
for mut desc_chain in &mut avail_iter {
|
||||
while let Some(mut desc_chain) = recv_queue.pop_descriptor_chain(self.mem.memory()) {
|
||||
let desc = desc_chain.next().unwrap();
|
||||
let len = cmp::min(desc.len() as u32, in_buffer.len() as u32);
|
||||
let source_slice = in_buffer.drain(..len as usize).collect::<Vec<u8>>();
|
||||
@@ -156,7 +155,7 @@ impl ConsoleEpollHandler {
|
||||
.translate_gva(self.access_platform.as_ref(), desc.len() as usize),
|
||||
) {
|
||||
error!("Failed to write slice: {:?}", e);
|
||||
avail_iter.go_to_previous_position();
|
||||
recv_queue.go_to_previous_position();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -188,7 +187,7 @@ impl ConsoleEpollHandler {
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
let mut used_count = 0;
|
||||
|
||||
for mut desc_chain in trans_queue.iter(self.mem.memory()).unwrap() {
|
||||
while let Some(mut desc_chain) = trans_queue.pop_descriptor_chain(self.mem.memory()) {
|
||||
let desc = desc_chain.next().unwrap();
|
||||
if let Some(ref mut out) = self.endpoint.out_file() {
|
||||
let _ = desc_chain.memory().write_to(
|
||||
|
||||
@@ -24,7 +24,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Barrier, Mutex, RwLock};
|
||||
use versionize::{VersionMap, Versionize, VersionizeResult};
|
||||
use versionize_derive::Versionize;
|
||||
use virtio_queue::{DescriptorChain, Queue, QueueOwnedT, QueueT};
|
||||
use virtio_queue::{DescriptorChain, Queue, QueueT};
|
||||
use vm_device::dma_mapping::ExternalDmaMapping;
|
||||
use vm_memory::{
|
||||
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic,
|
||||
@@ -676,7 +676,7 @@ impl IommuEpollHandler {
|
||||
fn request_queue(&mut self) -> bool {
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
let mut used_count = 0;
|
||||
for mut desc_chain in self.queues[0].iter(self.mem.memory()).unwrap() {
|
||||
while let Some(mut desc_chain) = self.queues[0].pop_descriptor_chain(self.mem.memory()) {
|
||||
let len = match Request::parse(
|
||||
&mut desc_chain,
|
||||
&self.mapping,
|
||||
|
||||
@@ -35,7 +35,7 @@ use std::sync::mpsc;
|
||||
use std::sync::{Arc, Barrier, Mutex};
|
||||
use versionize::{VersionMap, Versionize, VersionizeResult};
|
||||
use versionize_derive::Versionize;
|
||||
use virtio_queue::{DescriptorChain, Queue, QueueOwnedT, QueueT};
|
||||
use virtio_queue::{DescriptorChain, Queue, QueueT};
|
||||
use vm_device::dma_mapping::ExternalDmaMapping;
|
||||
use vm_memory::{
|
||||
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic,
|
||||
@@ -668,7 +668,7 @@ impl MemEpollHandler {
|
||||
let mut request_list = Vec::new();
|
||||
let mut used_count = 0;
|
||||
|
||||
for mut desc_chain in self.queue.iter(self.mem.memory()).unwrap() {
|
||||
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),
|
||||
|
||||
@@ -28,7 +28,7 @@ use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, Barrier};
|
||||
use versionize::{VersionMap, Versionize, VersionizeResult};
|
||||
use versionize_derive::Versionize;
|
||||
use virtio_queue::{DescriptorChain, Queue, QueueOwnedT, QueueT};
|
||||
use virtio_queue::{DescriptorChain, Queue, QueueT};
|
||||
use vm_memory::{
|
||||
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic,
|
||||
GuestMemoryError, GuestMemoryLoadGuard,
|
||||
@@ -180,7 +180,7 @@ impl PmemEpollHandler {
|
||||
fn process_queue(&mut self) -> bool {
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
let mut used_count = 0;
|
||||
for mut desc_chain in self.queue.iter(self.mem.memory()).unwrap() {
|
||||
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) => {
|
||||
let status_code = match self.disk.sync_all() {
|
||||
|
||||
@@ -22,7 +22,7 @@ use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, Barrier};
|
||||
use versionize::{VersionMap, Versionize, VersionizeResult};
|
||||
use versionize_derive::Versionize;
|
||||
use virtio_queue::{Queue, QueueOwnedT, QueueT};
|
||||
use virtio_queue::{Queue, QueueT};
|
||||
use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic};
|
||||
use vm_migration::VersionMapped;
|
||||
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
|
||||
@@ -52,7 +52,7 @@ impl RngEpollHandler {
|
||||
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
let mut used_count = 0;
|
||||
for mut desc_chain in queue.iter(self.mem.memory()).unwrap() {
|
||||
while let Some(mut desc_chain) = queue.pop_descriptor_chain(self.mem.memory()) {
|
||||
let desc = desc_chain.next().unwrap();
|
||||
let mut len = 0;
|
||||
|
||||
|
||||
@@ -128,10 +128,7 @@ where
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
let mut used_count = 0;
|
||||
|
||||
let mut avail_iter = self.queues[0]
|
||||
.iter(self.mem.memory())
|
||||
.map_err(DeviceError::QueueIterator)?;
|
||||
for mut desc_chain in &mut avail_iter {
|
||||
while let Some(mut desc_chain) = self.queues[0].pop_descriptor_chain(self.mem.memory()) {
|
||||
let used_len = match VsockPacket::from_rx_virtq_head(
|
||||
&mut desc_chain,
|
||||
self.access_platform.as_ref(),
|
||||
@@ -142,7 +139,7 @@ where
|
||||
} else {
|
||||
// We are using a consuming iterator over the virtio buffers, so, if we can't
|
||||
// fill in this buffer, we'll need to undo the last iterator step.
|
||||
avail_iter.go_to_previous_position();
|
||||
self.queues[0].go_to_previous_position();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -179,10 +176,7 @@ where
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
let mut used_count = 0;
|
||||
|
||||
let mut avail_iter = self.queues[1]
|
||||
.iter(self.mem.memory())
|
||||
.map_err(DeviceError::QueueIterator)?;
|
||||
for mut desc_chain in &mut avail_iter {
|
||||
while let Some(mut desc_chain) = self.queues[1].pop_descriptor_chain(self.mem.memory()) {
|
||||
let pkt = match VsockPacket::from_tx_virtq_head(
|
||||
&mut desc_chain,
|
||||
self.access_platform.as_ref(),
|
||||
@@ -197,7 +191,7 @@ where
|
||||
};
|
||||
|
||||
if self.backend.write().unwrap().send_pkt(&pkt).is_err() {
|
||||
avail_iter.go_to_previous_position();
|
||||
self.queues[1].go_to_previous_position();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use std::sync::{Arc, Barrier, Mutex};
|
||||
use std::time::Instant;
|
||||
use versionize::{VersionMap, Versionize, VersionizeResult};
|
||||
use versionize_derive::Versionize;
|
||||
use virtio_queue::{Queue, QueueOwnedT, QueueT};
|
||||
use virtio_queue::{Queue, QueueT};
|
||||
use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic};
|
||||
use vm_migration::VersionMapped;
|
||||
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
|
||||
@@ -66,7 +66,7 @@ impl WatchdogEpollHandler {
|
||||
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(self.mem.memory()).unwrap() {
|
||||
while let Some(mut desc_chain) = queue.pop_descriptor_chain(self.mem.memory()) {
|
||||
let desc = desc_chain.next().unwrap();
|
||||
|
||||
let mut len = 0;
|
||||
|
||||
Reference in New Issue
Block a user