From 0e72d9b5ed7a0eee2ea5ab27083dd32dcefbf132 Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Sat, 21 Dec 2024 00:54:15 +0000 Subject: [PATCH] block: increase the size of temporary vectors The size was set to one because without VIRTIO_BLK_F_SEG_MAX, the guest only used one data descriptor per request. The value 32 is empirically derived from booting a guest. This value eliminates all SmallVec allocations observable by DHAT. Signed-off-by: Wei Liu --- block/src/lib.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/block/src/lib.rs b/block/src/lib.rs index 8f70805cc..904c0a9cd 100644 --- a/block/src/lib.rs +++ b/block/src/lib.rs @@ -220,6 +220,8 @@ fn sector( mem.read_obj(addr).map_err(Error::GuestMemory) } +const DEFAULT_DESCRIPTOR_VEC_SIZE: usize = 32; + #[derive(Debug)] pub struct AlignedOperation { origin_ptr: u64, @@ -232,10 +234,10 @@ pub struct AlignedOperation { pub struct Request { pub request_type: RequestType, pub sector: u64, - pub data_descriptors: SmallVec<[(GuestAddress, u32); 1]>, + pub data_descriptors: SmallVec<[(GuestAddress, u32); DEFAULT_DESCRIPTOR_VEC_SIZE]>, pub status_addr: GuestAddress, pub writeback: bool, - pub aligned_operations: SmallVec<[AlignedOperation; 1]>, + pub aligned_operations: SmallVec<[AlignedOperation; DEFAULT_DESCRIPTOR_VEC_SIZE]>, pub start: Instant, } @@ -263,10 +265,10 @@ impl Request { let mut req = Request { request_type: request_type(desc_chain.memory(), hdr_desc_addr)?, sector: sector(desc_chain.memory(), hdr_desc_addr)?, - data_descriptors: SmallVec::with_capacity(1), + data_descriptors: SmallVec::with_capacity(DEFAULT_DESCRIPTOR_VEC_SIZE), status_addr: GuestAddress(0), writeback: true, - aligned_operations: SmallVec::with_capacity(1), + aligned_operations: SmallVec::with_capacity(DEFAULT_DESCRIPTOR_VEC_SIZE), start: Instant::now(), }; @@ -398,7 +400,7 @@ impl Request { let request_type = self.request_type; let offset = (sector << SECTOR_SHIFT) as libc::off_t; - let mut iovecs: SmallVec<[libc::iovec; 1]> = + let mut iovecs: SmallVec<[libc::iovec; DEFAULT_DESCRIPTOR_VEC_SIZE]> = SmallVec::with_capacity(self.data_descriptors.len()); for (data_addr, data_len) in &self.data_descriptors { if *data_len == 0 { @@ -653,7 +655,8 @@ where completion_list: &mut VecDeque<(u64, i32)>, ) -> AsyncIoResult<()> { // Convert libc::iovec into IoSliceMut - let mut slices: SmallVec<[IoSliceMut; 1]> = SmallVec::with_capacity(iovecs.len()); + let mut slices: SmallVec<[IoSliceMut; DEFAULT_DESCRIPTOR_VEC_SIZE]> = + SmallVec::with_capacity(iovecs.len()); for iovec in iovecs.iter() { // SAFETY: on Linux IoSliceMut wraps around libc::iovec slices.push(IoSliceMut::new(unsafe { @@ -690,7 +693,8 @@ where completion_list: &mut VecDeque<(u64, i32)>, ) -> AsyncIoResult<()> { // Convert libc::iovec into IoSlice - let mut slices: SmallVec<[IoSlice; 1]> = SmallVec::with_capacity(iovecs.len()); + let mut slices: SmallVec<[IoSlice; DEFAULT_DESCRIPTOR_VEC_SIZE]> = + SmallVec::with_capacity(iovecs.len()); for iovec in iovecs.iter() { // SAFETY: on Linux IoSlice wraps around libc::iovec slices.push(IoSlice::new(unsafe {