mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: Use SmallVec for descriptor chains
Rather than instantiating a vector for parsing the descriptor chain in advance instead use a SmallVec bounded by the expected length of the descriptor chain. This removes vector allocations from those paths. As smallvec was already a block dependency move it to a workspace dependency and use it from there. Fixes: #5079 Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2707,6 +2707,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"serial_buffer",
|
"serial_buffer",
|
||||||
|
"smallvec",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"vhost",
|
"vhost",
|
||||||
"virtio-bindings",
|
"virtio-bindings",
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ rustls = { version = "0.23.40", default-features = false, features = [
|
|||||||
sha2 = "0.11.0"
|
sha2 = "0.11.0"
|
||||||
signal-hook = "0.4.4"
|
signal-hook = "0.4.4"
|
||||||
signal-hook-registry = "1.4.8"
|
signal-hook-registry = "1.4.8"
|
||||||
|
smallvec = "1.15.1"
|
||||||
thiserror = "2.0.18"
|
thiserror = "2.0.18"
|
||||||
uuid = { version = "1.23.2" }
|
uuid = { version = "1.23.2" }
|
||||||
wait-timeout = "0.2.1"
|
wait-timeout = "0.2.1"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ libc = { workspace = true }
|
|||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
remain = "0.2.15"
|
remain = "0.2.15"
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
smallvec = "1.15.1"
|
smallvec = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
uuid = { workspace = true, features = ["v4"] }
|
uuid = { workspace = true, features = ["v4"] }
|
||||||
virtio-bindings = { workspace = true }
|
virtio-bindings = { workspace = true }
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ serde_with = { workspace = true, default-features = false, features = [
|
|||||||
"macros",
|
"macros",
|
||||||
] }
|
] }
|
||||||
serial_buffer = { path = "../serial_buffer" }
|
serial_buffer = { path = "../serial_buffer" }
|
||||||
|
smallvec = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
vhost = { workspace = true, features = [
|
vhost = { workspace = true, features = [
|
||||||
"vhost-kern",
|
"vhost-kern",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use event_monitor::event;
|
|||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use seccompiler::SeccompAction;
|
use seccompiler::SeccompAction;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use smallvec::SmallVec;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use virtio_queue::{Queue, QueueT};
|
use virtio_queue::{Queue, QueueT};
|
||||||
use vm_allocator::page_size::{align_page_size_down, get_page_size};
|
use vm_allocator::page_size::{align_page_size_down, get_page_size};
|
||||||
@@ -276,7 +277,7 @@ impl BalloonEpollHandler {
|
|||||||
{
|
{
|
||||||
let data_chunk_size = size_of::<u32>();
|
let data_chunk_size = size_of::<u32>();
|
||||||
|
|
||||||
let results: Vec<_> = desc_chain
|
let results: SmallVec<[_; 4]> = desc_chain
|
||||||
.checked_iter(self.access_platform.as_deref())
|
.checked_iter(self.access_platform.as_deref())
|
||||||
.collect();
|
.collect();
|
||||||
for result in results {
|
for result in results {
|
||||||
@@ -366,7 +367,7 @@ impl BalloonEpollHandler {
|
|||||||
self.queues[queue_index].pop_descriptor_chain(self.mem.memory())
|
self.queues[queue_index].pop_descriptor_chain(self.mem.memory())
|
||||||
{
|
{
|
||||||
let mut descs_len = 0;
|
let mut descs_len = 0;
|
||||||
let results: Vec<_> = desc_chain
|
let results: SmallVec<[_; 4]> = desc_chain
|
||||||
.checked_iter(self.access_platform.as_deref())
|
.checked_iter(self.access_platform.as_deref())
|
||||||
.collect();
|
.collect();
|
||||||
for result in results {
|
for result in results {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use log::{error, info, warn};
|
|||||||
use seccompiler::SeccompAction;
|
use seccompiler::SeccompAction;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serial_buffer::SerialBuffer;
|
use serial_buffer::SerialBuffer;
|
||||||
|
use smallvec::SmallVec;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use virtio_queue::{Queue, QueueT};
|
use virtio_queue::{Queue, QueueT};
|
||||||
use vm_memory::{ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic};
|
use vm_memory::{ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic};
|
||||||
@@ -205,7 +206,7 @@ impl ConsoleEpollHandler {
|
|||||||
|
|
||||||
// Validate all descriptors upfront so we never partially fill
|
// Validate all descriptors upfront so we never partially fill
|
||||||
// buffers for a chain that turns out to be invalid.
|
// buffers for a chain that turns out to be invalid.
|
||||||
let descs: Vec<_> = desc_chain
|
let descs: SmallVec<[_; 4]> = desc_chain
|
||||||
.checked_iter(self.access_platform.as_deref())
|
.checked_iter(self.access_platform.as_deref())
|
||||||
.collect::<Result<_, _>>()
|
.collect::<Result<_, _>>()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
@@ -253,7 +254,7 @@ impl ConsoleEpollHandler {
|
|||||||
let mut used_descs = false;
|
let mut used_descs = false;
|
||||||
|
|
||||||
while let Some(mut desc_chain) = trans_queue.pop_descriptor_chain(self.mem.memory()) {
|
while let Some(mut desc_chain) = trans_queue.pop_descriptor_chain(self.mem.memory()) {
|
||||||
let results: Vec<_> = desc_chain
|
let results: SmallVec<[_; 4]> = desc_chain
|
||||||
.checked_iter(self.access_platform.as_deref())
|
.checked_iter(self.access_platform.as_deref())
|
||||||
.collect();
|
.collect();
|
||||||
for result in results {
|
for result in results {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use event_monitor::event;
|
|||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use seccompiler::SeccompAction;
|
use seccompiler::SeccompAction;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use smallvec::SmallVec;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use virtio_queue::{Queue, QueueT};
|
use virtio_queue::{Queue, QueueT};
|
||||||
use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic};
|
use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic};
|
||||||
@@ -66,7 +67,7 @@ impl RngEpollHandler {
|
|||||||
// Validate the entire descriptor chain upfront so we never
|
// Validate the entire descriptor chain upfront so we never
|
||||||
// partially fill buffers for a chain that turns out to be
|
// partially fill buffers for a chain that turns out to be
|
||||||
// invalid.
|
// invalid.
|
||||||
let descs: Vec<_> = desc_chain
|
let descs: SmallVec<[_; 4]> = desc_chain
|
||||||
.checked_iter(self.access_platform.as_deref())
|
.checked_iter(self.access_platform.as_deref())
|
||||||
.collect::<Result<_, _>>()
|
.collect::<Result<_, _>>()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|||||||
Reference in New Issue
Block a user