mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-18 10:59:16 +00:00
virtio-devices: net: reduce vec allocations for iovec conversion
Signed-off-by: ihciah <ihciah@gmail.com>
This commit is contained in:
parent
9113544e21
commit
3320015793
@ -19,6 +19,7 @@ use vm_virtio::{AccessPlatform, Translatable};
|
|||||||
pub struct TxVirtio {
|
pub struct TxVirtio {
|
||||||
pub counter_bytes: Wrapping<u64>,
|
pub counter_bytes: Wrapping<u64>,
|
||||||
pub counter_frames: Wrapping<u64>,
|
pub counter_frames: Wrapping<u64>,
|
||||||
|
iovecs: IovecBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TxVirtio {
|
impl Default for TxVirtio {
|
||||||
@ -32,6 +33,7 @@ impl TxVirtio {
|
|||||||
TxVirtio {
|
TxVirtio {
|
||||||
counter_bytes: Wrapping(0),
|
counter_bytes: Wrapping(0),
|
||||||
counter_frames: Wrapping(0),
|
counter_frames: Wrapping(0),
|
||||||
|
iovecs: IovecBuffer::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ impl TxVirtio {
|
|||||||
|
|
||||||
let mut next_desc = desc_chain.next();
|
let mut next_desc = desc_chain.next();
|
||||||
|
|
||||||
let mut iovecs = Vec::new();
|
let mut iovecs = self.iovecs.borrow();
|
||||||
while let Some(desc) = next_desc {
|
while let Some(desc) = next_desc {
|
||||||
let desc_addr = desc
|
let desc_addr = desc
|
||||||
.addr()
|
.addr()
|
||||||
@ -145,6 +147,7 @@ impl TxVirtio {
|
|||||||
pub struct RxVirtio {
|
pub struct RxVirtio {
|
||||||
pub counter_bytes: Wrapping<u64>,
|
pub counter_bytes: Wrapping<u64>,
|
||||||
pub counter_frames: Wrapping<u64>,
|
pub counter_frames: Wrapping<u64>,
|
||||||
|
iovecs: IovecBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RxVirtio {
|
impl Default for RxVirtio {
|
||||||
@ -158,6 +161,7 @@ impl RxVirtio {
|
|||||||
RxVirtio {
|
RxVirtio {
|
||||||
counter_bytes: Wrapping(0),
|
counter_bytes: Wrapping(0),
|
||||||
counter_frames: Wrapping(0),
|
counter_frames: Wrapping(0),
|
||||||
|
iovecs: IovecBuffer::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +197,7 @@ impl RxVirtio {
|
|||||||
.ok_or(NetQueuePairError::DescriptorInvalidHeader)?;
|
.ok_or(NetQueuePairError::DescriptorInvalidHeader)?;
|
||||||
let mut next_desc = Some(desc);
|
let mut next_desc = Some(desc);
|
||||||
|
|
||||||
let mut iovecs = Vec::new();
|
let mut iovecs = self.iovecs.borrow();
|
||||||
while let Some(desc) = next_desc {
|
while let Some(desc) = next_desc {
|
||||||
let desc_addr = desc
|
let desc_addr = desc
|
||||||
.addr()
|
.addr()
|
||||||
@ -288,6 +292,53 @@ impl RxVirtio {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
struct IovecBuffer(Vec<libc::iovec>);
|
||||||
|
|
||||||
|
// SAFETY: Implementing Send for IovecBuffer is safe as the pointer inside is iovec.
|
||||||
|
// The iovecs are usually constructed from virtio descriptors, which are safe to send across
|
||||||
|
// threads.
|
||||||
|
unsafe impl Send for IovecBuffer {}
|
||||||
|
// SAFETY: Implementing Sync for IovecBuffer is safe as the pointer inside is iovec.
|
||||||
|
// The iovecs are usually constructed from virtio descriptors, which are safe to access from
|
||||||
|
// multiple threads.
|
||||||
|
unsafe impl Sync for IovecBuffer {}
|
||||||
|
|
||||||
|
impl IovecBuffer {
|
||||||
|
fn new() -> Self {
|
||||||
|
// Here we use 4 as the default capacity because it is enough for most cases.
|
||||||
|
const DEFAULT_CAPACITY: usize = 4;
|
||||||
|
IovecBuffer(Vec::with_capacity(DEFAULT_CAPACITY))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn borrow(&mut self) -> IovecBufferBorrowed<'_> {
|
||||||
|
IovecBufferBorrowed(&mut self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IovecBufferBorrowed<'a>(&'a mut Vec<libc::iovec>);
|
||||||
|
|
||||||
|
impl<'a> std::ops::Deref for IovecBufferBorrowed<'a> {
|
||||||
|
type Target = Vec<libc::iovec>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> std::ops::DerefMut for IovecBufferBorrowed<'a> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for IovecBufferBorrowed<'_> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Clear the buffer to make sure old values are not used after
|
||||||
|
self.0.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct NetCounters {
|
pub struct NetCounters {
|
||||||
pub tx_bytes: Arc<AtomicU64>,
|
pub tx_bytes: Arc<AtomicU64>,
|
||||||
|
Loading…
Reference in New Issue
Block a user