Skip to content

Commit acb79a2

Browse files
Manciukicroypat
authored andcommitted
refactor: add trait function const_device_type to use in Sized contexts
By defining an associated function to the trait, we can simplify the logic to execute code on a specific device from the VMM, while also statically guaranteeing we are passing the right constant. The downside is that we need both a sized and a dyn implementation for the function. To ensure devices implement them correctly, a utility macro is provided. We cannot do it as a default trait impl as the const_ variant is only defined on Sized. Signed-off-by: Riccardo Mancini <[email protected]>
1 parent 26fd798 commit acb79a2

File tree

12 files changed

+68
-89
lines changed

12 files changed

+68
-89
lines changed

src/vmm/src/device_manager/mmio.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ pub(crate) mod tests {
468468
use crate::test_utils::multi_region_mem_raw;
469469
use crate::vstate::kvm::Kvm;
470470
use crate::vstate::memory::{GuestAddress, GuestMemoryMmap};
471-
use crate::{Vm, arch};
471+
use crate::{Vm, arch, impl_device_type};
472472

473473
const QUEUE_SIZES: &[u16] = &[64];
474474

@@ -522,6 +522,8 @@ pub(crate) mod tests {
522522
}
523523

524524
impl VirtioDevice for DummyDevice {
525+
impl_device_type!(0);
526+
525527
fn avail_features(&self) -> u64 {
526528
0
527529
}
@@ -532,10 +534,6 @@ pub(crate) mod tests {
532534

533535
fn set_acked_features(&mut self, _: u64) {}
534536

535-
fn device_type(&self) -> u32 {
536-
0
537-
}
538-
539537
fn queues(&self) -> &[Queue] {
540538
&self.queues
541539
}

src/vmm/src/device_manager/mod.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,6 @@ impl DeviceManager {
373373
/// Run fn `f()` for the virtio device matching `virtio_type` and `id`.
374374
pub fn try_with_virtio_device_with_id<T, F, R, E>(
375375
&self,
376-
virtio_type: u32,
377376
id: &str,
378377
f: F,
379378
) -> Result<R, FindDeviceError>
@@ -382,7 +381,7 @@ impl DeviceManager {
382381
E: std::error::Error + 'static + Send + Sync,
383382
F: FnOnce(&mut T) -> Result<R, E>,
384383
{
385-
if let Some(device) = self.get_virtio_device(virtio_type, id) {
384+
if let Some(device) = self.get_virtio_device(T::const_device_type(), id) {
386385
let mut dev = device.lock().expect("Poisoned lock");
387386
f(dev
388387
.as_mut_any()
@@ -395,19 +394,12 @@ impl DeviceManager {
395394
}
396395

397396
/// Run fn `f()` for the virtio device matching `virtio_type` and `id`.
398-
pub fn with_virtio_device_with_id<T, F, R>(
399-
&self,
400-
virtio_type: u32,
401-
id: &str,
402-
f: F,
403-
) -> Result<R, FindDeviceError>
397+
pub fn with_virtio_device_with_id<T, F, R>(&self, id: &str, f: F) -> Result<R, FindDeviceError>
404398
where
405399
T: VirtioDevice + 'static + Debug,
406400
F: FnOnce(&mut T) -> R,
407401
{
408-
self.try_with_virtio_device_with_id(virtio_type, id, |dev: &mut T| {
409-
Ok::<R, FindDeviceError>(f(dev))
410-
})
402+
self.try_with_virtio_device_with_id(id, |dev: &mut T| Ok::<R, FindDeviceError>(f(dev)))
411403
}
412404
}
413405

src/vmm/src/devices/virtio/balloon/device.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ use crate::devices::virtio::generated::virtio_ids::VIRTIO_ID_BALLOON;
3131
use crate::devices::virtio::queue::InvalidAvailIdx;
3232
use crate::devices::virtio::transport::{VirtioInterrupt, VirtioInterruptType};
3333
use crate::logger::IncMetric;
34-
use crate::mem_size_mib;
3534
use crate::utils::u64_to_usize;
3635
use crate::vstate::memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryMmap};
36+
use crate::{impl_device_type, mem_size_mib};
3737

3838
const SIZE_OF_U32: usize = std::mem::size_of::<u32>();
3939
const SIZE_OF_STAT: usize = std::mem::size_of::<BalloonStat>();
@@ -544,6 +544,8 @@ impl Balloon {
544544
}
545545

546546
impl VirtioDevice for Balloon {
547+
impl_device_type!(VIRTIO_ID_BALLOON);
548+
547549
fn avail_features(&self) -> u64 {
548550
self.avail_features
549551
}
@@ -556,10 +558,6 @@ impl VirtioDevice for Balloon {
556558
self.acked_features = acked_features;
557559
}
558560

559-
fn device_type(&self) -> u32 {
560-
VIRTIO_ID_BALLOON
561-
}
562-
563561
fn queues(&self) -> &[Queue] {
564562
&self.queues
565563
}

src/vmm/src/devices/virtio/block/device.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::devices::virtio::device::VirtioDevice;
1616
use crate::devices::virtio::generated::virtio_ids::VIRTIO_ID_BLOCK;
1717
use crate::devices::virtio::queue::{InvalidAvailIdx, Queue};
1818
use crate::devices::virtio::transport::VirtioInterrupt;
19+
use crate::impl_device_type;
1920
use crate::rate_limiter::BucketUpdate;
2021
use crate::snapshot::Persist;
2122
use crate::vmm_config::drive::BlockDeviceConfig;
@@ -132,6 +133,8 @@ impl Block {
132133
}
133134

134135
impl VirtioDevice for Block {
136+
impl_device_type!(VIRTIO_ID_BLOCK);
137+
135138
fn avail_features(&self) -> u64 {
136139
match self {
137140
Self::Virtio(b) => b.avail_features,
@@ -153,10 +156,6 @@ impl VirtioDevice for Block {
153156
}
154157
}
155158

156-
fn device_type(&self) -> u32 {
157-
VIRTIO_ID_BLOCK
158-
}
159-
160159
fn queues(&self) -> &[Queue] {
161160
match self {
162161
Self::Virtio(b) => &b.queues,

src/vmm/src/devices/virtio/block/vhost_user/device.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::devices::virtio::vhost_user::{VhostUserHandleBackend, VhostUserHandle
2727
use crate::devices::virtio::vhost_user_metrics::{
2828
VhostUserDeviceMetrics, VhostUserMetricsPerDevice,
2929
};
30+
use crate::impl_device_type;
3031
use crate::logger::{IncMetric, StoreMetric, log_dev_preview_warning};
3132
use crate::utils::u64_to_usize;
3233
use crate::vmm_config::drive::BlockDeviceConfig;
@@ -287,6 +288,8 @@ impl<T: VhostUserHandleBackend> VhostUserBlockImpl<T> {
287288
}
288289

289290
impl<T: VhostUserHandleBackend + Send + 'static> VirtioDevice for VhostUserBlockImpl<T> {
291+
impl_device_type!(VIRTIO_ID_BLOCK);
292+
290293
fn avail_features(&self) -> u64 {
291294
self.avail_features
292295
}
@@ -299,10 +302,6 @@ impl<T: VhostUserHandleBackend + Send + 'static> VirtioDevice for VhostUserBlock
299302
self.acked_features = acked_features;
300303
}
301304

302-
fn device_type(&self) -> u32 {
303-
VIRTIO_ID_BLOCK
304-
}
305-
306305
fn queues(&self) -> &[Queue] {
307306
&self.queues
308307
}

src/vmm/src/devices/virtio/block/virtio/device.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use crate::devices::virtio::generated::virtio_ids::VIRTIO_ID_BLOCK;
3434
use crate::devices::virtio::generated::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
3535
use crate::devices::virtio::queue::{InvalidAvailIdx, Queue};
3636
use crate::devices::virtio::transport::{VirtioInterrupt, VirtioInterruptType};
37+
use crate::impl_device_type;
3738
use crate::logger::{IncMetric, error, warn};
3839
use crate::rate_limiter::{BucketUpdate, RateLimiter};
3940
use crate::utils::u64_to_usize;
@@ -582,6 +583,8 @@ impl VirtioBlock {
582583
}
583584

584585
impl VirtioDevice for VirtioBlock {
586+
impl_device_type!(VIRTIO_ID_BLOCK);
587+
585588
fn avail_features(&self) -> u64 {
586589
self.avail_features
587590
}
@@ -594,10 +597,6 @@ impl VirtioDevice for VirtioBlock {
594597
self.acked_features = acked_features;
595598
}
596599

597-
fn device_type(&self) -> u32 {
598-
VIRTIO_ID_BLOCK
599-
}
600-
601600
fn queues(&self) -> &[Queue] {
602601
&self.queues
603602
}

src/vmm/src/devices/virtio/device.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,14 @@ pub trait VirtioDevice: AsAny + Send {
7474
(self.acked_features() & (1 << feature)) != 0
7575
}
7676

77+
/// The virtio device type (as a constant of the struct).
78+
fn const_device_type() -> u32
79+
where
80+
Self: Sized;
81+
7782
/// The virtio device type.
83+
///
84+
/// It should be the same as returned by Self::const_device_type().
7885
fn device_type(&self) -> u32;
7986

8087
/// Returns the device queues.
@@ -170,6 +177,20 @@ impl fmt::Debug for dyn VirtioDevice {
170177
}
171178
}
172179

180+
/// Utility to define both const_device_type and device_type with a u32 constant
181+
#[macro_export]
182+
macro_rules! impl_device_type {
183+
($const_type:expr) => {
184+
fn const_device_type() -> u32 {
185+
$const_type
186+
}
187+
188+
fn device_type(&self) -> u32 {
189+
Self::const_device_type()
190+
}
191+
};
192+
}
193+
173194
#[cfg(test)]
174195
pub(crate) mod tests {
175196
use super::*;
@@ -180,6 +201,8 @@ pub(crate) mod tests {
180201
}
181202

182203
impl VirtioDevice for MockVirtioDevice {
204+
impl_device_type!(0);
205+
183206
fn avail_features(&self) -> u64 {
184207
todo!()
185208
}
@@ -192,10 +215,6 @@ pub(crate) mod tests {
192215
todo!()
193216
}
194217

195-
fn device_type(&self) -> u32 {
196-
todo!()
197-
}
198-
199218
fn queues(&self) -> &[Queue] {
200219
todo!()
201220
}

src/vmm/src/devices/virtio/net/device.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use crate::devices::virtio::transport::{VirtioInterrupt, VirtioInterruptType};
4040
use crate::devices::{DeviceError, report_net_event_fail};
4141
use crate::dumbo::pdu::arp::ETH_IPV4_FRAME_LEN;
4242
use crate::dumbo::pdu::ethernet::{EthernetFrame, PAYLOAD_OFFSET};
43+
use crate::impl_device_type;
4344
use crate::logger::{IncMetric, METRICS};
4445
use crate::mmds::data_store::Mmds;
4546
use crate::mmds::ns::MmdsNetworkStack;
@@ -961,6 +962,8 @@ impl Net {
961962
}
962963

963964
impl VirtioDevice for Net {
965+
impl_device_type!(VIRTIO_ID_NET);
966+
964967
fn avail_features(&self) -> u64 {
965968
self.avail_features
966969
}
@@ -973,10 +976,6 @@ impl VirtioDevice for Net {
973976
self.acked_features = acked_features;
974977
}
975978

976-
fn device_type(&self) -> u32 {
977-
VIRTIO_ID_NET
978-
}
979-
980979
fn queues(&self) -> &[Queue] {
981980
&self.queues
982981
}

src/vmm/src/devices/virtio/rng/device.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::devices::virtio::iov_deque::IovDequeError;
2121
use crate::devices::virtio::iovec::IoVecBufferMut;
2222
use crate::devices::virtio::queue::{FIRECRACKER_MAX_QUEUE_SIZE, InvalidAvailIdx, Queue};
2323
use crate::devices::virtio::transport::{VirtioInterrupt, VirtioInterruptType};
24+
use crate::impl_device_type;
2425
use crate::logger::{IncMetric, debug, error};
2526
use crate::rate_limiter::{RateLimiter, TokenType};
2627
use crate::vstate::memory::GuestMemoryMmap;
@@ -253,9 +254,7 @@ impl Entropy {
253254
}
254255

255256
impl VirtioDevice for Entropy {
256-
fn device_type(&self) -> u32 {
257-
VIRTIO_ID_RNG
258-
}
257+
impl_device_type!(VIRTIO_ID_RNG);
259258

260259
fn queues(&self) -> &[Queue] {
261260
&self.queues

src/vmm/src/devices/virtio/transport/mmio.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ pub(crate) mod tests {
476476
use super::*;
477477
use crate::devices::virtio::ActivateError;
478478
use crate::devices::virtio::device_status::DEVICE_NEEDS_RESET;
479+
use crate::impl_device_type;
479480
use crate::test_utils::single_region_mem;
480481
use crate::utils::byte_order::{read_le_u32, write_le_u32};
481482
use crate::utils::u64_to_usize;
@@ -516,6 +517,8 @@ pub(crate) mod tests {
516517
}
517518

518519
impl VirtioDevice for DummyDevice {
520+
impl_device_type!(123);
521+
519522
fn avail_features(&self) -> u64 {
520523
self.avail_features
521524
}
@@ -528,10 +531,6 @@ pub(crate) mod tests {
528531
self.acked_features = acked_features;
529532
}
530533

531-
fn device_type(&self) -> u32 {
532-
123
533-
}
534-
535534
fn queues(&self) -> &[Queue] {
536535
&self.queues
537536
}

0 commit comments

Comments
 (0)