dragonball: unify the metric interface of legacy device

Fixes: #7248

Signed-off-by: Songqian Li <mail@lisongqian.cn>
This commit is contained in:
Songqian Li
2023-10-18 13:54:24 +08:00
parent b508091305
commit 65213e9fbe
4 changed files with 53 additions and 18 deletions

View File

@@ -30,17 +30,21 @@ pub struct I8042DeviceMetrics {
pub type I8042Device = I8042Wrapper<EventFdTrigger>;
pub struct I8042Wrapper<T: Trigger> {
pub device: I8042Dev<T>,
pub metrics: Arc<I8042DeviceMetrics>,
device: I8042Dev<T>,
metrics: Arc<I8042DeviceMetrics>,
}
impl I8042Device {
pub fn new(event: EventFdTrigger, metrics: Arc<I8042DeviceMetrics>) -> Self {
pub fn new(event: EventFdTrigger) -> Self {
Self {
device: I8042Dev::new(event),
metrics,
metrics: Arc::new(I8042DeviceMetrics::default()),
}
}
pub fn metrics(&self) -> Arc<I8042DeviceMetrics> {
self.metrics.clone()
}
}
impl DeviceIoMut for I8042Wrapper<EventFdTrigger> {

View File

@@ -6,14 +6,16 @@
//!
//! This module implements a PL031 Real Time Clock (RTC) that provides to provides long time base counter.
use std::convert::TryInto;
use std::sync::Arc;
use dbs_device::{DeviceIoMut, IoAddress};
use dbs_utils::metric::{IncMetric, SharedIncMetric};
use log::warn;
use serde::Serialize;
use vm_superio::rtc_pl031::{Rtc, RtcEvents};
/// Metrics specific to the RTC device
#[derive(Default)]
#[derive(Default, Serialize)]
pub struct RTCDeviceMetrics {
/// Errors triggered while using the RTC device.
pub error_count: SharedIncMetric,
@@ -37,7 +39,7 @@ impl RtcEvents for RTCDeviceMetrics {
/// The wrapper of Rtc struct to implement DeviceIoMut trait.
pub struct RTCDevice {
pub rtc: Rtc<RTCDeviceMetrics>,
rtc: Rtc<Arc<RTCDeviceMetrics>>,
}
impl Default for RTCDevice {
@@ -48,11 +50,15 @@ impl Default for RTCDevice {
impl RTCDevice {
pub fn new() -> Self {
let metrics = RTCDeviceMetrics::default();
let metrics = Arc::new(RTCDeviceMetrics::default());
Self {
rtc: Rtc::with_events(metrics),
}
}
pub fn metrics(&self) -> Arc<RTCDeviceMetrics> {
Arc::clone(self.rtc.events())
}
}
impl DeviceIoMut for RTCDevice {

View File

@@ -96,6 +96,10 @@ impl SerialDevice {
out,
}
}
pub fn metrics(&mut self) -> Arc<SerialDeviceMetrics> {
self.serial.events().metrics.clone()
}
}
pub struct SerialWrapper<T: Trigger, EV: SerialEvents> {

View File

@@ -17,6 +17,8 @@ use dbs_legacy_devices::RTCDevice;
use dbs_legacy_devices::SerialDevice;
use vmm_sys_util::eventfd::EventFd;
use crate::metric::METRICS;
// The I8042 Data Port (IO Port 0x60) is used for reading data that was received from a I8042 device or from the I8042 controller itself and writing data to a I8042 device or to the I8042 controller itself.
const I8042_DATA_PORT: u16 = 0x60;
@@ -71,11 +73,13 @@ pub(crate) mod x86_64 {
use super::*;
use dbs_device::device_manager::IoManager;
use dbs_device::resources::Resource;
use dbs_legacy_devices::{EventFdTrigger, I8042Device, I8042DeviceMetrics};
use dbs_legacy_devices::{EventFdTrigger, I8042Device};
use kvm_ioctls::VmFd;
pub(crate) const COM1_NAME: &str = "com1";
pub(crate) const COM1_IRQ: u32 = 4;
pub(crate) const COM1_PORT1: u16 = 0x3f8;
pub(crate) const COM2_NAME: &str = "com2";
pub(crate) const COM2_IRQ: u32 = 3;
pub(crate) const COM2_PORT1: u16 = 0x2f8;
@@ -86,14 +90,22 @@ pub(crate) mod x86_64 {
pub fn create_manager(bus: &mut IoManager, vm_fd: Option<Arc<VmFd>>) -> Result<Self> {
let (com1_device, com1_eventfd) =
Self::create_com_device(bus, vm_fd.as_ref(), COM1_IRQ, COM1_PORT1)?;
METRICS.write().unwrap().serial.insert(
String::from(COM1_NAME),
com1_device.lock().unwrap().metrics(),
);
let (com2_device, com2_eventfd) =
Self::create_com_device(bus, vm_fd.as_ref(), COM2_IRQ, COM2_PORT1)?;
METRICS.write().unwrap().serial.insert(
String::from(COM2_NAME),
com2_device.lock().unwrap().metrics(),
);
let exit_evt = EventFd::new(libc::EFD_NONBLOCK).map_err(Error::EventFd)?;
let i8042_device = Arc::new(Mutex::new(I8042Device::new(
EventFdTrigger::new(exit_evt.try_clone().map_err(Error::EventFd)?),
Arc::new(I8042DeviceMetrics::default()),
)));
let i8042_device = Arc::new(Mutex::new(I8042Device::new(EventFdTrigger::new(
exit_evt.try_clone().map_err(Error::EventFd)?,
))));
METRICS.write().unwrap().i8042 = i8042_device.lock().unwrap().metrics();
let resources = [Resource::PioAddressRange {
// 0x60 and 0x64 are the io ports that i8042 devices used.
// We register pio address range from 0x60 - 0x64 with base I8042_DATA_PORT for i8042 to use.
@@ -157,11 +169,11 @@ pub(crate) mod aarch64 {
type Result<T> = ::std::result::Result<T, Error>;
/// LegacyDeviceType: com1
pub const COM1: &str = "com1";
pub const COM1_NAME: &str = "com1";
/// LegacyDeviceType: com2
pub const COM2: &str = "com2";
pub const COM2_NAME: &str = "com2";
/// LegacyDeviceType: rtc
pub const RTC: &str = "rtc";
pub const RTC_NAME: &str = "rtc";
impl LegacyDeviceManager {
/// Create a LegacyDeviceManager instance handling legacy devices.
@@ -171,11 +183,20 @@ pub(crate) mod aarch64 {
resources: &HashMap<String, DeviceResources>,
) -> Result<Self> {
let (com1_device, com1_eventfd) =
Self::create_com_device(bus, vm_fd.as_ref(), resources.get(COM1).unwrap())?;
Self::create_com_device(bus, vm_fd.as_ref(), resources.get(COM1_NAME).unwrap())?;
METRICS.write().unwrap().serial.insert(
String::from(COM1_NAME),
com1_device.lock().unwrap().metrics(),
);
let (com2_device, com2_eventfd) =
Self::create_com_device(bus, vm_fd.as_ref(), resources.get(COM2).unwrap())?;
Self::create_com_device(bus, vm_fd.as_ref(), resources.get(COM2_NAME).unwrap())?;
METRICS.write().unwrap().serial.insert(
String::from(COM2_NAME),
com2_device.lock().unwrap().metrics(),
);
let (rtc_device, rtc_eventfd) =
Self::create_rtc_device(bus, vm_fd.as_ref(), resources.get(RTC).unwrap())?;
Self::create_rtc_device(bus, vm_fd.as_ref(), resources.get(RTC_NAME).unwrap())?;
METRICS.write().unwrap().rtc = rtc_device.lock().unwrap().metrics();
Ok(LegacyDeviceManager {
_rtc_device: rtc_device,