Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c22249e

Browse files
feat(virtio-mem): add metrics for virtio-mem device
Wire support for virtio-mem metrics, adding a few basic metrics: queue events, queue event fails, activation fails. Signed-off-by: Riccardo Mancini <mancio@amazon.com>
1 parent 3466ef1 commit c22249e

File tree

5 files changed

+96
-2
lines changed

5 files changed

+96
-2
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::devices::virtio::generated::virtio_mem::{
2323
VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, virtio_mem_config,
2424
};
2525
use crate::devices::virtio::iov_deque::IovDequeError;
26+
use crate::devices::virtio::mem::metrics::METRICS;
2627
use crate::devices::virtio::mem::{VIRTIO_MEM_DEV_ID, VIRTIO_MEM_GUEST_ADDRESS};
2728
use crate::devices::virtio::queue::{FIRECRACKER_MAX_QUEUE_SIZE, InvalidAvailIdx, Queue};
2829
use crate::devices::virtio::transport::{VirtioInterrupt, VirtioInterruptType};
@@ -170,12 +171,15 @@ impl VirtioMem {
170171
}
171172

172173
pub(crate) fn process_mem_queue_event(&mut self) {
174+
METRICS.queue_event_count.inc();
173175
if let Err(err) = self.queue_events[MEM_QUEUE].read() {
176+
METRICS.queue_event_fails.inc();
174177
error!("Failed to read mem queue event: {err}");
175178
return;
176179
}
177180

178181
if let Err(err) = self.process_mem_queue() {
182+
METRICS.queue_event_fails.inc();
179183
error!("virtio-mem: Failed to process queue: {err}");
180184
}
181185
}
@@ -263,7 +267,7 @@ impl VirtioDevice for VirtioMem {
263267
error!(
264268
"virtio-mem: VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE feature not acknowledged by guest"
265269
);
266-
// TODO(virtio-mem): activation failed metric
270+
METRICS.activate_fails.inc();
267271
return Err(ActivateError::RequiredFeatureNotAcked(
268272
"VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE",
269273
));
@@ -276,7 +280,7 @@ impl VirtioDevice for VirtioMem {
276280

277281
self.device_state = DeviceState::Activated(ActiveState { mem, interrupt });
278282
if self.activate_event.write(1).is_err() {
279-
// TODO(virtio-mem): activation failed metric
283+
METRICS.activate_fails.inc();
280284
self.device_state = DeviceState::Inactive;
281285
return Err(ActivateError::EventFd);
282286
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Defines the metrics system for memory devices.
5+
//!
6+
//! # Metrics format
7+
//! The metrics are flushed in JSON when requested by vmm::logger::metrics::METRICS.write().
8+
//!
9+
//! ## JSON example with metrics:
10+
//! ```json
11+
//! "memory_hotplug": {
12+
//! "activate_fails": "SharedIncMetric",
13+
//! "queue_event_fails": "SharedIncMetric",
14+
//! "queue_event_count": "SharedIncMetric",
15+
//! ...
16+
//! }
17+
//! }
18+
//! ```
19+
//! Each `memory` field in the example above is a serializable `VirtioMemDeviceMetrics` structure
20+
//! collecting metrics such as `activate_fails`, `queue_event_fails` etc. for the memoty hotplug
21+
//! device.
22+
//! Since Firecrakcer only supports one virtio-mem device, there is no per device metrics and
23+
//! `memory_hotplug` represents the aggregate entropy metrics.
24+
25+
use serde::ser::SerializeMap;
26+
use serde::{Serialize, Serializer};
27+
28+
use crate::logger::{LatencyAggregateMetrics, SharedIncMetric};
29+
30+
/// Stores aggregated virtio-mem metrics
31+
pub(super) static METRICS: VirtioMemDeviceMetrics = VirtioMemDeviceMetrics::new();
32+
33+
/// Called by METRICS.flush(), this function facilitates serialization of virtio-mem device metrics.
34+
pub fn flush_metrics<S: Serializer>(serializer: S) -> Result<S::Ok, S::Error> {
35+
let mut seq = serializer.serialize_map(Some(1))?;
36+
seq.serialize_entry("memory_hotplug", &METRICS)?;
37+
seq.end()
38+
}
39+
40+
#[derive(Debug, Serialize)]
41+
pub(super) struct VirtioMemDeviceMetrics {
42+
/// Number of device activation failures
43+
pub activate_fails: SharedIncMetric,
44+
/// Number of queue event handling failures
45+
pub queue_event_fails: SharedIncMetric,
46+
/// Number of queue events handled
47+
pub queue_event_count: SharedIncMetric,
48+
}
49+
50+
impl VirtioMemDeviceMetrics {
51+
/// Const default construction.
52+
const fn new() -> Self {
53+
Self {
54+
activate_fails: SharedIncMetric::new(),
55+
queue_event_fails: SharedIncMetric::new(),
56+
queue_event_count: SharedIncMetric::new(),
57+
}
58+
}
59+
}
60+
61+
#[cfg(test)]
62+
pub mod tests {
63+
use super::*;
64+
use crate::logger::IncMetric;
65+
66+
#[test]
67+
fn test_memory_hotplug_metrics() {
68+
let mem_metrics: VirtioMemDeviceMetrics = VirtioMemDeviceMetrics::new();
69+
let mem_metrics_local: String = serde_json::to_string(&mem_metrics).unwrap();
70+
// the 1st serialize flushes the metrics and resets values to 0 so that
71+
// we can compare the values with local metrics.
72+
serde_json::to_string(&METRICS).unwrap();
73+
let mem_metrics_global: String = serde_json::to_string(&METRICS).unwrap();
74+
assert_eq!(mem_metrics_local, mem_metrics_global);
75+
mem_metrics.queue_event_count.inc();
76+
assert_eq!(mem_metrics.queue_event_count.count(), 1);
77+
}
78+
}

‎src/vmm/src/devices/virtio/mem/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
mod device;
55
mod event_handler;
6+
pub mod metrics;
67
pub mod persist;
78

89
use vm_memory::GuestAddress;

‎src/vmm/src/logger/metrics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ use super::FcLineWriter;
7474
use crate::devices::legacy;
7575
use crate::devices::virtio::balloon::metrics as balloon_metrics;
7676
use crate::devices::virtio::block::virtio::metrics as block_metrics;
77+
use crate::devices::virtio::mem::metrics as virtio_mem_metrics;
7778
use crate::devices::virtio::net::metrics as net_metrics;
7879
use crate::devices::virtio::rng::metrics as entropy_metrics;
7980
use crate::devices::virtio::vhost_user_metrics;
@@ -873,6 +874,7 @@ create_serialize_proxy!(BalloonMetricsSerializeProxy, balloon_metrics);
873874
create_serialize_proxy!(EntropyMetricsSerializeProxy, entropy_metrics);
874875
create_serialize_proxy!(VsockMetricsSerializeProxy, vsock_metrics);
875876
create_serialize_proxy!(LegacyDevMetricsSerializeProxy, legacy);
877+
create_serialize_proxy!(MemoryHotplugSerializeProxy, virtio_mem_metrics);
876878

877879
/// Structure storing all metrics while enforcing serialization support on them.
878880
#[derive(Debug, Default, Serialize)]
@@ -923,6 +925,9 @@ pub struct FirecrackerMetrics {
923925
#[serde(flatten)]
924926
/// Vhost-user device related metrics.
925927
pub vhost_user_ser: VhostUserMetricsSerializeProxy,
928+
#[serde(flatten)]
929+
/// Virtio-mem device related metrics (memory hotplugging)
930+
pub memory_hotplug_ser: MemoryHotplugSerializeProxy,
926931
}
927932
impl FirecrackerMetrics {
928933
/// Const default construction.
@@ -948,6 +953,7 @@ impl FirecrackerMetrics {
948953
vsock_ser: VsockMetricsSerializeProxy {},
949954
entropy_ser: EntropyMetricsSerializeProxy {},
950955
vhost_user_ser: VhostUserMetricsSerializeProxy {},
956+
memory_hotplug_ser: MemoryHotplugSerializeProxy {},
951957
}
952958
}
953959
}

‎tests/host_tools/fcmetrics.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@ def validate_fc_metrics(metrics):
300300
"entropy_rate_limiter_throttled",
301301
"rate_limiter_event_count",
302302
],
303+
"memory_hotplug": [
304+
"activate_fails",
305+
"queue_event_fails",
306+
"queue_event_count",
307+
]
303308
}
304309

305310
# validate timestamp before jsonschema validation which some more time

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /