Skip to content

perf(drivers): Use smallvec for AvailBufferToken #1728

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions src/drivers/fs/virtio_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use alloc::vec::Vec;
use core::str;

use pci_types::InterruptLine;
use smallvec::SmallVec;
use virtio::FeatureBits;
use virtio::fs::ConfigVolatileFieldAccess;
use volatile::VolatileRef;
Expand Down Expand Up @@ -168,23 +169,26 @@ impl FuseInterface for VirtioFsDriver {
payload: cmd_payload_opt,
} = cmd;
let send = if let Some(cmd_payload) = cmd_payload_opt {
vec![
SmallVec::from_buf([
BufferElem::Sized(cmd_headers),
BufferElem::Vector(cmd_payload),
]
])
} else {
vec![BufferElem::Sized(cmd_headers)]
let mut vec = SmallVec::new();
vec.push(BufferElem::Sized(cmd_headers));
vec
};

let rsp_headers = Box::<RspHeader<O>, _>::new_uninit_in(DeviceAlloc);
let recv = if rsp_payload_len == 0 {
vec![BufferElem::Sized(rsp_headers)]
let mut vec = SmallVec::new();
vec.push(BufferElem::Sized(rsp_headers));
vec
} else {
let rsp_payload = Vec::with_capacity_in(rsp_payload_len as usize, DeviceAlloc);
vec![
SmallVec::from_buf([
BufferElem::Sized(rsp_headers),
BufferElem::Vector(rsp_payload),
]
BufferElem::Vector(Vec::with_capacity_in(rsp_payload_len as usize, DeviceAlloc)),
])
};

let buffer_tkn = AvailBufferToken::new(send, recv).unwrap();
Expand Down
11 changes: 6 additions & 5 deletions src/drivers/net/virtio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ cfg_if::cfg_if! {
use alloc::boxed::Box;
use alloc::vec::Vec;

use smallvec::SmallVec;
use smoltcp::phy::{Checksum, ChecksumCapabilities};
use smoltcp::wire::{ETHERNET_HEADER_LEN, EthernetFrame, Ipv4Packet, Ipv6Packet};
use virtio::net::{ConfigVolatileFieldAccess, Hdr, HdrF};
Expand Down Expand Up @@ -114,14 +115,14 @@ impl RxQueues {
fn fill_queue(vq: &mut VirtQueue, num_packets: u16, packet_size: u32) {
for _ in 0..num_packets {
let buff_tkn = match AvailBufferToken::new(
vec![],
vec![
SmallVec::new(),
SmallVec::from_buf([
BufferElem::Sized(Box::<Hdr, _>::new_uninit_in(DeviceAlloc)),
BufferElem::Vector(Vec::with_capacity_in(
packet_size.try_into().unwrap(),
DeviceAlloc,
)),
],
]),
) {
Ok(tkn) => tkn,
Err(_vq_err) => {
Expand Down Expand Up @@ -292,8 +293,8 @@ impl NetworkDriver for VirtioNetDriver {
}

let buff_tkn = AvailBufferToken::new(
vec![BufferElem::Sized(header), BufferElem::Vector(packet)],
vec![],
SmallVec::from_buf([BufferElem::Sized(header), BufferElem::Vector(packet)]),
SmallVec::new(),
)
.unwrap();

Expand Down
14 changes: 9 additions & 5 deletions src/drivers/virtio/virtqueue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use core::mem::MaybeUninit;
use core::{mem, ptr};

use enum_dispatch::enum_dispatch;
use smallvec::SmallVec;
use virtio::{le32, le64, pvirtq, virtq};

use self::error::VirtqError;
Expand Down Expand Up @@ -396,8 +397,8 @@ impl BufferElem {
/// respective virtqueue.
/// The maximum number of descriptors per buffer is bounded by the size of the virtqueue.
pub struct AvailBufferToken {
pub(crate) send_buff: Vec<BufferElem>,
pub(crate) recv_buff: Vec<BufferElem>,
pub(crate) send_buff: SmallVec<[BufferElem; 2]>,
pub(crate) recv_buff: SmallVec<[BufferElem; 2]>,
}

pub(crate) struct UsedDeviceWritableBuffer {
Expand Down Expand Up @@ -450,7 +451,7 @@ impl UsedDeviceWritableBuffer {
}

pub(crate) struct UsedBufferToken {
pub send_buff: Vec<BufferElem>,
pub send_buff: SmallVec<[BufferElem; 2]>,
pub used_recv_buff: UsedDeviceWritableBuffer,
}

Expand All @@ -459,7 +460,7 @@ impl UsedBufferToken {
Self {
send_buff: tkn.send_buff,
used_recv_buff: UsedDeviceWritableBuffer {
elems: tkn.recv_buff.into(),
elems: tkn.recv_buff.into_vec().into(),
remaining_written_len: written_len,
},
}
Expand Down Expand Up @@ -492,7 +493,10 @@ impl AvailBufferToken {
/// ```
/// they must split the structure after the send part and provide the respective part via the send argument and the respective other
/// part via the recv argument.
pub fn new(send_buff: Vec<BufferElem>, recv_buff: Vec<BufferElem>) -> Result<Self, VirtqError> {
pub fn new(
send_buff: SmallVec<[BufferElem; 2]>,
recv_buff: SmallVec<[BufferElem; 2]>,
) -> Result<Self, VirtqError> {
if send_buff.is_empty() && recv_buff.is_empty() {
return Err(VirtqError::BufferNotSpecified);
}
Expand Down
17 changes: 13 additions & 4 deletions src/drivers/vsock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use alloc::vec::Vec;
use core::mem;

use pci_types::InterruptLine;
use smallvec::SmallVec;
use virtio::FeatureBits;
use virtio::vsock::Hdr;

Expand All @@ -28,14 +29,14 @@ use crate::mm::device_alloc::DeviceAlloc;
fn fill_queue(vq: &mut VirtQueue, num_packets: u16, packet_size: u32) {
for _ in 0..num_packets {
let buff_tkn = match AvailBufferToken::new(
vec![],
vec![
SmallVec::new(),
SmallVec::from_buf([
BufferElem::Sized(Box::<Hdr, _>::new_uninit_in(DeviceAlloc)),
BufferElem::Vector(Vec::with_capacity_in(
packet_size.try_into().unwrap(),
DeviceAlloc,
)),
],
]),
) {
Ok(tkn) => tkn,
Err(_vq_err) => {
Expand Down Expand Up @@ -171,7 +172,15 @@ impl TxQueue {
result
};

let buff_tkn = AvailBufferToken::new(vec![BufferElem::Vector(packet)], vec![]).unwrap();
let buff_tkn = AvailBufferToken::new(
{
let mut vec = SmallVec::new();
vec.push(BufferElem::Vector(packet));
vec
},
SmallVec::new(),
)
.unwrap();

vq.dispatch(buff_tkn, false, BufferType::Direct).unwrap();

Expand Down