From 49c2e6e23c4671c87e9b05634ea8ccdcfcfcad4d Mon Sep 17 00:00:00 2001 From: Xuewei Niu Date: Mon, 13 Nov 2023 11:44:25 +0800 Subject: [PATCH] dragonball: Remove vhost-net dependency on virtio-net This patch is to remove vhost-net dependency on virtio-net for dbs-virtio-devices crate. Then, the feature of vhost-net is able to enable without enabling virtio-net device, error, etc. Fixes: #8423 Signed-off-by: Xuewei Niu --- src/dragonball/src/api/v1/virtio_net.rs | 12 ++++- src/dragonball/src/api/v1/vmm_action.rs | 3 ++ .../src/dbs_virtio_devices/Cargo.toml | 2 +- .../src/dbs_virtio_devices/src/lib.rs | 53 +++++++++++++++++-- .../src/dbs_virtio_devices/src/net.rs | 47 ++-------------- .../src/vhost/vhost_kern/net.rs | 6 +-- 6 files changed, 70 insertions(+), 53 deletions(-) diff --git a/src/dragonball/src/api/v1/virtio_net.rs b/src/dragonball/src/api/v1/virtio_net.rs index 61ce65e76fd1..d2acde677fed 100644 --- a/src/dragonball/src/api/v1/virtio_net.rs +++ b/src/dragonball/src/api/v1/virtio_net.rs @@ -3,6 +3,8 @@ // // SPDX-License-Identifier: Apache-2.0 +use core::panic; + use dbs_utils::net::MacAddr; use serde::{Deserialize, Serialize}; @@ -29,8 +31,14 @@ pub enum Backend { } impl Default for Backend { + #[allow(unreachable_code)] fn default() -> Self { - Self::Virtio(VirtioConfig::default()) + #[cfg(feature = "virtio-net")] + return Self::Virtio(VirtioConfig::default()); + #[cfg(feature = "vhost-net")] + return Self::Vhost(VirtioConfig::default()); + + panic!("no available default network backend") } } @@ -86,6 +94,7 @@ impl From<&NetworkInterfaceConfig> for VirtioNetDeviceConfigInfo { .unwrap_or(virtio_net_dev_mgr::DEFAULT_QUEUE_SIZE); // It is safe because we tested the type of config before. + #[allow(unreachable_patterns)] let config = match &value.backend { Backend::Virtio(config) => config, _ => panic!("The virtio backend config is invalid: {:?}", value), @@ -125,6 +134,7 @@ impl From<&NetworkInterfaceConfig> for VhostNetDeviceConfigInfo { .unwrap_or(vhost_net_dev_mgr::DEFAULT_QUEUE_SIZE); // It is safe because we tested the type of config before. + #[allow(unreachable_patterns)] let config = match &value.backend { Backend::Vhost(config) => config, _ => panic!("The virtio backend config is invalid: {:?}", value), diff --git a/src/dragonball/src/api/v1/vmm_action.rs b/src/dragonball/src/api/v1/vmm_action.rs index 681ddaed1252..97214cb4e3e6 100644 --- a/src/dragonball/src/api/v1/vmm_action.rs +++ b/src/dragonball/src/api/v1/vmm_action.rs @@ -200,6 +200,8 @@ pub enum VmmAction { #[cfg(feature = "virtio-net")] /// Update a network interface, after microVM start. Currently, the only updatable properties /// are the RX and TX rate limiters. + /// TODO: vhost-net rate limiters aren't implemented, see: + /// https://github.com/kata-containers/kata-containers/issues/8327 UpdateNetworkInterface(VirtioNetDeviceConfigUpdateInfo), #[cfg(feature = "virtio-fs")] @@ -318,6 +320,7 @@ impl VmmService { VmmAction::RemoveBlockDevice(drive_id) => { self.remove_block_device(vmm, event_mgr, &drive_id) } + #[cfg(any(feature = "virtio-net", feature = "vhost-net"))] VmmAction::InsertNetworkDevice(config) => match config.backend { #[cfg(feature = "virtio-net")] Backend::Virtio(_) => self.add_virtio_net_device(vmm, event_mgr, config.into()), diff --git a/src/dragonball/src/dbs_virtio_devices/Cargo.toml b/src/dragonball/src/dbs_virtio_devices/Cargo.toml index 8b9c3d4c8832..9299915ad9b7 100644 --- a/src/dragonball/src/dbs_virtio_devices/Cargo.toml +++ b/src/dragonball/src/dbs_virtio_devices/Cargo.toml @@ -52,4 +52,4 @@ virtio-fs-pro = ["virtio-fs", "nydus-storage/backend-registry", "nydus-storage/b virtio-mem = ["virtio-mmio"] virtio-balloon = ["virtio-mmio"] vhost = ["virtio-mmio", "vhost-rs/vhost-user-master", "vhost-rs/vhost-kern"] -vhost-net = ["virtio-net", "vhost", "vhost-rs/vhost-net"] +vhost-net = ["vhost", "vhost-rs/vhost-net"] diff --git a/src/dragonball/src/dbs_virtio_devices/src/lib.rs b/src/dragonball/src/dbs_virtio_devices/src/lib.rs index 9262550f62d3..59727b090378 100644 --- a/src/dragonball/src/dbs_virtio_devices/src/lib.rs +++ b/src/dragonball/src/dbs_virtio_devices/src/lib.rs @@ -46,7 +46,10 @@ pub mod vhost; use std::io::Error as IOError; -use net::NetError; +#[cfg(any(feature = "virtio-net", feature = "vhost-net"))] +use dbs_utils::metric::SharedIncMetric; +#[cfg(any(feature = "virtio-net", feature = "vhost-net"))] +use serde::Serialize; use virtio_queue::Error as VqError; use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemoryError}; @@ -212,7 +215,7 @@ pub enum Error { #[cfg(feature = "virtio-net")] #[error("virtio-net error: {0:?}")] - VirtioNet(NetError), + VirtioNet(net::NetError), #[cfg(feature = "vhost-net")] #[error("vhost-net error: {0:?}")] @@ -229,7 +232,7 @@ pub enum Error { } // Error for tap devices -#[cfg(feature = "virtio-net")] +#[cfg(any(feature = "virtio-net", feature = "vhost-net"))] #[derive(Debug, thiserror::Error)] pub enum TapError { #[error("missing {0} flags")] @@ -240,7 +243,7 @@ pub enum TapError { #[error("failed to set vnet_hdr_size: {0}")] SetVnetHdrSize(#[source] dbs_utils::net::TapError), - + #[error("failed to open a tap device: {0}")] Open(#[source] dbs_utils::net::TapError), @@ -248,6 +251,48 @@ pub enum TapError { Enable(#[source] dbs_utils::net::TapError), } +#[cfg(any(feature = "virtio-net", feature = "vhost-net"))] +#[inline] +pub fn vnet_hdr_len() -> usize { + std::mem::size_of::() +} + +/// Metrics specific to the net device. +#[cfg(any(feature = "virtio-net", feature = "vhost-net"))] +#[derive(Default, Serialize)] +pub struct NetDeviceMetrics { + /// Number of times when handling events on a network device. + pub event_count: SharedIncMetric, + /// Number of times when activate failed on a network device. + pub activate_fails: SharedIncMetric, + /// Number of times when interacting with the space config of a network device failed. + pub cfg_fails: SharedIncMetric, + /// Number of times when handling events on a network device failed. + pub event_fails: SharedIncMetric, + /// Number of events associated with the receiving queue. + pub rx_queue_event_count: SharedIncMetric, + /// Number of events associated with the rate limiter installed on the receiving path. + pub rx_event_rate_limiter_count: SharedIncMetric, + /// Number of events received on the associated tap. + pub rx_tap_event_count: SharedIncMetric, + /// Number of bytes received. + pub rx_bytes_count: SharedIncMetric, + /// Number of packets received. + pub rx_packets_count: SharedIncMetric, + /// Number of errors while receiving data. + pub rx_fails: SharedIncMetric, + /// Number of transmitted bytes. + pub tx_bytes_count: SharedIncMetric, + /// Number of errors while transmitting data. + pub tx_fails: SharedIncMetric, + /// Number of transmitted packets. + pub tx_packets_count: SharedIncMetric, + /// Number of events associated with the transmitting queue. + pub tx_queue_event_count: SharedIncMetric, + /// Number of events associated with the rate limiter installed on the transmitting path. + pub tx_rate_limiter_event_count: SharedIncMetric, +} + /// Specialized std::result::Result for Virtio device operations. pub type Result = std::result::Result; diff --git a/src/dragonball/src/dbs_virtio_devices/src/net.rs b/src/dragonball/src/dbs_virtio_devices/src/net.rs index 671873ade508..27cdab1d4169 100644 --- a/src/dragonball/src/dbs_virtio_devices/src/net.rs +++ b/src/dragonball/src/dbs_virtio_devices/src/net.rs @@ -9,7 +9,6 @@ use std::any::Any; use std::cmp; use std::io::{self, Read, Write}; use std::marker::PhantomData; -use std::mem; use std::ops::Deref; use std::os::unix::io::AsRawFd; use std::sync::{mpsc, Arc}; @@ -18,12 +17,11 @@ use dbs_device::resources::ResourceConstraint; use dbs_utils::epoll_manager::{ EpollManager, EventOps, EventSet, Events, MutEventSubscriber, SubscriberId, }; -use dbs_utils::metric::{IncMetric, SharedIncMetric}; +use dbs_utils::metric::IncMetric; use dbs_utils::net::{net_gen, MacAddr, Tap, MAC_ADDR_LEN}; use dbs_utils::rate_limiter::{BucketUpdate, RateLimiter, TokenType}; use libc; use log::{debug, error, info, trace, warn}; -use serde::Serialize; use virtio_bindings::bindings::virtio_net::*; use virtio_queue::{QueueOwnedT, QueueSync, QueueT}; use vm_memory::{Bytes, GuestAddress, GuestAddressSpace, GuestMemoryRegion, GuestRegionMmap}; @@ -31,8 +29,8 @@ use vmm_sys_util::eventfd::EventFd; use crate::device::{VirtioDeviceConfig, VirtioDeviceInfo}; use crate::{ - ActivateError, ActivateResult, ConfigResult, DbsGuestAddressSpace, Error, Result, TapError, - VirtioDevice, VirtioQueueConfig, TYPE_NET, + vnet_hdr_len, ActivateError, ActivateResult, ConfigResult, DbsGuestAddressSpace, Error, + NetDeviceMetrics, Result, TapError, VirtioDevice, VirtioQueueConfig, TYPE_NET, }; const NET_DRIVER_NAME: &str = "virtio-net"; @@ -64,41 +62,6 @@ pub enum NetError { TapError(#[source] TapError), } -/// Metrics specific to the net device. -#[derive(Default, Serialize)] -pub struct NetDeviceMetrics { - /// Number of times when handling events on a network device. - pub event_count: SharedIncMetric, - /// Number of times when activate failed on a network device. - pub activate_fails: SharedIncMetric, - /// Number of times when interacting with the space config of a network device failed. - pub cfg_fails: SharedIncMetric, - /// Number of times when handling events on a network device failed. - pub event_fails: SharedIncMetric, - /// Number of events associated with the receiving queue. - pub rx_queue_event_count: SharedIncMetric, - /// Number of events associated with the rate limiter installed on the receiving path. - pub rx_event_rate_limiter_count: SharedIncMetric, - /// Number of events received on the associated tap. - pub rx_tap_event_count: SharedIncMetric, - /// Number of bytes received. - pub rx_bytes_count: SharedIncMetric, - /// Number of packets received. - pub rx_packets_count: SharedIncMetric, - /// Number of errors while receiving data. - pub rx_fails: SharedIncMetric, - /// Number of transmitted bytes. - pub tx_bytes_count: SharedIncMetric, - /// Number of errors while transmitting data. - pub tx_fails: SharedIncMetric, - /// Number of transmitted packets. - pub tx_packets_count: SharedIncMetric, - /// Number of events associated with the transmitting queue. - pub tx_queue_event_count: SharedIncMetric, - /// Number of events associated with the rate limiter installed on the transmitting path. - pub tx_rate_limiter_event_count: SharedIncMetric, -} - struct TxVirtio { queue: VirtioQueueConfig, rate_limiter: RateLimiter, @@ -143,10 +106,6 @@ impl RxVirtio { } } -pub fn vnet_hdr_len() -> usize { - mem::size_of::() -} - #[allow(dead_code)] pub(crate) struct NetEpollHandler< AS: GuestAddressSpace, diff --git a/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_kern/net.rs b/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_kern/net.rs index beb7ba99d019..2b9a379de566 100644 --- a/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_kern/net.rs +++ b/src/dragonball/src/dbs_virtio_devices/src/vhost/vhost_kern/net.rs @@ -31,14 +31,14 @@ use virtio_bindings::bindings::virtio_ring::*; use virtio_queue::{Descriptor, DescriptorChain, QueueT}; use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryRegion, MemoryRegionAddress}; -use crate::net::{vnet_hdr_len, NetDeviceMetrics}; #[cfg(test)] use crate::vhost::vhost_kern::test_utils::{ MockVhostBackend as VhostBackend, MockVhostNet as VhostNet, }; use crate::{ - ActivateError, ConfigResult, DbsGuestAddressSpace, Error as VirtioError, - Result as VirtioResult, TapError, VirtioDevice, VirtioDeviceConfig, VirtioDeviceInfo, TYPE_NET, + vnet_hdr_len, ActivateError, ConfigResult, DbsGuestAddressSpace, Error as VirtioError, + NetDeviceMetrics, Result as VirtioResult, TapError, VirtioDevice, VirtioDeviceConfig, + VirtioDeviceInfo, TYPE_NET, }; const NET_DRIVER_NAME: &str = "vhost-net";