Skip to content

Commit 50c057d

Browse files
committed
refactor: make net and block devices own metrics creation
Signed-off-by: aerosouund <aerosound161@gmail.com>
1 parent ff95558 commit 50c057d

6 files changed

Lines changed: 46 additions & 95 deletions

File tree

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use super::request::*;
2424
use super::{BLOCK_QUEUE_SIZES, SECTOR_SHIFT, SECTOR_SIZE, VirtioBlockError, io as block_io};
2525
use crate::devices::virtio::ActivateError;
2626
use crate::devices::virtio::block::CacheType;
27-
use crate::devices::virtio::block::virtio::metrics::{BlockDeviceMetrics, BlockMetricsPerDevice};
27+
use crate::devices::virtio::block::virtio::metrics::{BlockDeviceMetrics, METRICS};
2828
use crate::devices::virtio::device::{ActiveState, DeviceState, VirtioDevice, VirtioDeviceType};
2929
use crate::devices::virtio::generated::virtio_blk::{
3030
VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_RO, VIRTIO_BLK_ID_BYTES,
@@ -314,6 +314,11 @@ impl VirtioBlock {
314314
let config_space = ConfigSpace {
315315
capacity: disk_properties.nsectors.to_le(),
316316
};
317+
let metrics = Arc::new(BlockDeviceMetrics::default());
318+
METRICS
319+
.write()
320+
.unwrap()
321+
.insert(config.drive_id.clone(), metrics.clone());
317322

318323
Ok(VirtioBlock {
319324
avail_features,
@@ -334,7 +339,7 @@ impl VirtioBlock {
334339
disk: disk_properties,
335340
rate_limiter,
336341
is_io_engine_throttled: false,
337-
metrics: BlockMetricsPerDevice::alloc(config.drive_id),
342+
metrics: metrics,
338343
})
339344
}
340345

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

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -86,50 +86,23 @@ use serde::{Serialize, Serializer};
8686

8787
use crate::logger::{IncMetric, LatencyAggregateMetrics, SharedIncMetric};
8888

89-
/// map of block drive id and metrics
90-
/// this should be protected by a lock before accessing.
91-
#[derive(Debug)]
92-
pub struct BlockMetricsPerDevice {
93-
/// used to access per block device metrics
94-
pub metrics: BTreeMap<String, Arc<BlockDeviceMetrics>>,
95-
}
96-
97-
impl BlockMetricsPerDevice {
98-
/// Allocate `BlockDeviceMetrics` for block device having
99-
/// id `drive_id`. Also, allocate only if it doesn't
100-
/// exist to avoid overwriting previously allocated data.
101-
/// lock is always initialized so it is safe the unwrap
102-
/// the lock without a check.
103-
pub fn alloc(drive_id: String) -> Arc<BlockDeviceMetrics> {
104-
Arc::clone(
105-
METRICS
106-
.write()
107-
.unwrap()
108-
.metrics
109-
.entry(drive_id)
110-
.or_insert_with(|| Arc::new(BlockDeviceMetrics::default())),
111-
)
112-
}
113-
}
114-
11589
/// Pool of block-related metrics per device behind a lock to
11690
/// keep things thread safe. Since the lock is initialized here
11791
/// it is safe to unwrap it without any check.
118-
static METRICS: RwLock<BlockMetricsPerDevice> = RwLock::new(BlockMetricsPerDevice {
119-
metrics: BTreeMap::new(),
120-
});
92+
pub static METRICS: RwLock<BTreeMap<String, Arc<BlockDeviceMetrics>>> =
93+
RwLock::new(BTreeMap::new());
12194

12295
/// This function facilitates aggregation and serialization of
12396
/// per block device metrics.
12497
pub fn flush_metrics<S: Serializer>(serializer: S) -> Result<S::Ok, S::Error> {
12598
let block_metrics = METRICS.read().unwrap();
126-
let metrics_len = block_metrics.metrics.len();
99+
let metrics_len = block_metrics.len();
127100
// +1 to accommodate aggregate block metrics
128101
let mut seq = serializer.serialize_map(Some(1 + metrics_len))?;
129102

130103
let mut block_aggregated: BlockDeviceMetrics = BlockDeviceMetrics::default();
131104

132-
for (name, metrics) in block_metrics.metrics.iter() {
105+
for (name, metrics) in block_metrics.iter() {
133106
let devn = format!("block_{}", name);
134107
// serialization will flush the metrics so aggregate before it.
135108
let m: &BlockDeviceMetrics = metrics;
@@ -247,10 +220,6 @@ pub mod tests {
247220
// devices on aarch64 but we stick to 19 to keep test common.
248221
const MAX_BLOCK_DEVICES: usize = 19;
249222

250-
// This is to make sure that RwLock for block::metrics::METRICS is good.
251-
drop(METRICS.read().unwrap());
252-
drop(METRICS.write().unwrap());
253-
254223
// block::metrics::METRICS is in short RwLock on Vec of BlockDeviceMetrics.
255224
// Normally, pointer to unique entries of block::metrics::METRICS are stored
256225
// in Block device so that Block device can do self.metrics.* to
@@ -264,7 +233,7 @@ pub mod tests {
264233
let mut metrics: Vec<Arc<BlockDeviceMetrics>> = Vec::new();
265234
for i in 0..MAX_BLOCK_DEVICES {
266235
let devn: String = format!("drv{}", i);
267-
metrics.push(BlockMetricsPerDevice::alloc(devn.clone()));
236+
metrics.push(Arc::new(BlockDeviceMetrics::default()));
268237
// update IncMetric
269238
metrics[i].activate_fails.inc();
270239
// update SharedMetric
@@ -296,11 +265,7 @@ pub mod tests {
296265
// `test_max_block_dev_metrics` which also uses the same name.
297266
let devn = "drv0";
298267

299-
// This is to make sure that RwLock for block::metrics::METRICS is good.
300-
drop(METRICS.read().unwrap());
301-
drop(METRICS.write().unwrap());
302-
303-
let test_metrics = BlockMetricsPerDevice::alloc(String::from(devn));
268+
let test_metrics = BlockDeviceMetrics::default();
304269
// Test to update IncMetrics
305270
test_metrics.activate_fails.inc();
306271
assert!(

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ use super::device::DiskProperties;
1111
use super::*;
1212
use crate::devices::virtio::block::persist::BlockConstructorArgs;
1313
use crate::devices::virtio::block::virtio::device::FileEngineType;
14-
use crate::devices::virtio::block::virtio::metrics::BlockMetricsPerDevice;
14+
use crate::devices::virtio::block::virtio::metrics::{BlockDeviceMetrics, METRICS};
1515
use crate::devices::virtio::device::{ActiveState, DeviceState, VirtioDeviceType};
1616
use crate::devices::virtio::generated::virtio_blk::VIRTIO_BLK_F_RO;
1717
use crate::devices::virtio::persist::VirtioDeviceState;
1818
use crate::rate_limiter::RateLimiter;
1919
use crate::rate_limiter::persist::RateLimiterState;
2020
use crate::snapshot::Persist;
2121

22+
use std::sync::Arc;
23+
2224
/// Holds info about block's file engine type. Gets saved in snapshot.
2325
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
2426
pub enum FileEngineTypeState {
@@ -114,6 +116,13 @@ impl Persist<'_> for VirtioBlock {
114116
capacity: disk_properties.nsectors.to_le(),
115117
};
116118

119+
let metrics = Arc::new(BlockDeviceMetrics::default());
120+
121+
METRICS
122+
.write()
123+
.unwrap()
124+
.insert(state.id.clone(), metrics.clone());
125+
117126
Ok(VirtioBlock {
118127
avail_features,
119128
acked_features,
@@ -133,7 +142,7 @@ impl Persist<'_> for VirtioBlock {
133142
disk: disk_properties,
134143
rate_limiter,
135144
is_io_engine_throttled: false,
136-
metrics: BlockMetricsPerDevice::alloc(state.id.clone()),
145+
metrics: metrics,
137146
})
138147
}
139148
}

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::devices::virtio::generated::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
2929
use crate::devices::virtio::iovec::{
3030
IoVecBuffer, IoVecBufferMut, IoVecError, ParsedDescriptorChain,
3131
};
32-
use crate::devices::virtio::net::metrics::{NetDeviceMetrics, NetMetricsPerDevice};
32+
use crate::devices::virtio::net::metrics::{METRICS as NETMETRICS, NetDeviceMetrics};
3333
use crate::devices::virtio::net::tap::Tap;
3434
use crate::devices::virtio::net::{
3535
MAX_BUFFER_SIZE, NET_QUEUE_SIZES, NetError, NetQueue, RX_INDEX, TX_INDEX, generated,
@@ -303,6 +303,11 @@ impl Net {
303303
queue_evts.push(EventFd::new(libc::EFD_NONBLOCK).map_err(NetError::EventFd)?);
304304
queues.push(Queue::new(size));
305305
}
306+
let metrics = Arc::new(NetDeviceMetrics::default());
307+
NETMETRICS
308+
.write()
309+
.unwrap()
310+
.insert(id.clone(), metrics.clone());
306311

307312
Ok(Net {
308313
id: id.clone(),
@@ -320,7 +325,7 @@ impl Net {
320325
device_state: DeviceState::Inactive,
321326
activate_evt: EventFd::new(libc::EFD_NONBLOCK).map_err(NetError::EventFd)?,
322327
mmds_ns: None,
323-
metrics: NetMetricsPerDevice::alloc(id),
328+
metrics: metrics,
324329
tx_buffer: Default::default(),
325330
rx_buffer: RxBuffers::new()?,
326331
})

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

Lines changed: 13 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -88,50 +88,22 @@ use serde::{Serialize, Serializer};
8888

8989
use crate::logger::{IncMetric, LatencyAggregateMetrics, SharedIncMetric};
9090

91-
/// map of network interface id and metrics
92-
/// this should be protected by a lock before accessing.
93-
#[derive(Debug)]
94-
pub struct NetMetricsPerDevice {
95-
/// used to access per net device metrics
96-
pub metrics: BTreeMap<String, Arc<NetDeviceMetrics>>,
97-
}
98-
99-
impl NetMetricsPerDevice {
100-
/// Allocate `NetDeviceMetrics` for net device having
101-
/// id `iface_id`. Also, allocate only if it doesn't
102-
/// exist to avoid overwriting previously allocated data.
103-
/// lock is always initialized so it is safe the unwrap
104-
/// the lock without a check.
105-
pub fn alloc(iface_id: String) -> Arc<NetDeviceMetrics> {
106-
Arc::clone(
107-
METRICS
108-
.write()
109-
.unwrap()
110-
.metrics
111-
.entry(iface_id)
112-
.or_insert_with(|| Arc::new(NetDeviceMetrics::default())),
113-
)
114-
}
115-
}
116-
11791
/// Pool of Network-related metrics per device behind a lock to
11892
/// keep things thread safe. Since the lock is initialized here
11993
/// it is safe to unwrap it without any check.
120-
static METRICS: RwLock<NetMetricsPerDevice> = RwLock::new(NetMetricsPerDevice {
121-
metrics: BTreeMap::new(),
122-
});
94+
pub static METRICS: RwLock<BTreeMap<String, Arc<NetDeviceMetrics>>> = RwLock::new(BTreeMap::new());
12395

12496
/// This function facilitates aggregation and serialization of
12597
/// per net device metrics.
12698
pub fn flush_metrics<S: Serializer>(serializer: S) -> Result<S::Ok, S::Error> {
12799
let net_metrics = METRICS.read().unwrap();
128-
let metrics_len = net_metrics.metrics.len();
100+
let metrics_len = net_metrics.len();
129101
// +1 to accomodate aggregate net metrics
130102
let mut seq = serializer.serialize_map(Some(1 + metrics_len))?;
131103

132104
let mut net_aggregated: NetDeviceMetrics = NetDeviceMetrics::default();
133105

134-
for (name, metrics) in net_metrics.metrics.iter() {
106+
for (name, metrics) in net_metrics.iter() {
135107
let devn = format!("net_{}", name);
136108
// serialization will flush the metrics so aggregate before it.
137109
let m: &NetDeviceMetrics = metrics;
@@ -280,27 +252,29 @@ pub mod tests {
280252

281253
for i in 0..MAX_NET_DEVICES {
282254
let devn: String = format!("eth{}", i);
283-
NetMetricsPerDevice::alloc(devn.clone());
255+
256+
METRICS
257+
.write()
258+
.unwrap()
259+
.insert(devn.to_string(), Arc::new(NetDeviceMetrics::default()));
260+
284261
METRICS
285262
.read()
286263
.unwrap()
287-
.metrics
288264
.get(&devn)
289265
.unwrap()
290266
.activate_fails
291267
.inc();
292268
METRICS
293269
.read()
294270
.unwrap()
295-
.metrics
296271
.get(&devn)
297272
.unwrap()
298273
.rx_bytes_count
299274
.add(10);
300275
METRICS
301276
.read()
302277
.unwrap()
303-
.metrics
304278
.get(&devn)
305279
.unwrap()
306280
.tx_bytes_count
@@ -313,7 +287,6 @@ pub mod tests {
313287
METRICS
314288
.read()
315289
.unwrap()
316-
.metrics
317290
.get(&devn)
318291
.unwrap()
319292
.activate_fails
@@ -324,7 +297,6 @@ pub mod tests {
324297
METRICS
325298
.read()
326299
.unwrap()
327-
.metrics
328300
.get(&devn)
329301
.unwrap()
330302
.rx_bytes_count
@@ -335,7 +307,6 @@ pub mod tests {
335307
METRICS
336308
.read()
337309
.unwrap()
338-
.metrics
339310
.get(&devn)
340311
.unwrap()
341312
.tx_bytes_count
@@ -353,13 +324,14 @@ pub mod tests {
353324
drop(METRICS.read().unwrap());
354325
drop(METRICS.write().unwrap());
355326

356-
NetMetricsPerDevice::alloc(String::from(devn));
357-
METRICS.read().unwrap().metrics.get(devn).unwrap();
327+
METRICS
328+
.write()
329+
.unwrap()
330+
.insert(devn.to_string(), Arc::new(NetDeviceMetrics::default()));
358331

359332
METRICS
360333
.read()
361334
.unwrap()
362-
.metrics
363335
.get(devn)
364336
.unwrap()
365337
.activate_fails
@@ -368,7 +340,6 @@ pub mod tests {
368340
METRICS
369341
.read()
370342
.unwrap()
371-
.metrics
372343
.get(devn)
373344
.unwrap()
374345
.activate_fails
@@ -378,7 +349,6 @@ pub mod tests {
378349
METRICS
379350
.read()
380351
.unwrap()
381-
.metrics
382352
.get(devn)
383353
.unwrap()
384354
.activate_fails
@@ -390,7 +360,6 @@ pub mod tests {
390360
METRICS
391361
.read()
392362
.unwrap()
393-
.metrics
394363
.get(devn)
395364
.unwrap()
396365
.activate_fails
@@ -400,7 +369,6 @@ pub mod tests {
400369
METRICS
401370
.read()
402371
.unwrap()
403-
.metrics
404372
.get(devn)
405373
.unwrap()
406374
.activate_fails
@@ -410,15 +378,13 @@ pub mod tests {
410378
METRICS
411379
.read()
412380
.unwrap()
413-
.metrics
414381
.get(devn)
415382
.unwrap()
416383
.activate_fails
417384
.inc();
418385
METRICS
419386
.read()
420387
.unwrap()
421-
.metrics
422388
.get(devn)
423389
.unwrap()
424390
.rx_bytes_count
@@ -427,7 +393,6 @@ pub mod tests {
427393
METRICS
428394
.read()
429395
.unwrap()
430-
.metrics
431396
.get(devn)
432397
.unwrap()
433398
.rx_bytes_count

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ mod tests {
496496
],
497497
);
498498

499+
let entropy_event_fails = th.device().metrics.entropy_event_fails.count();
500+
let entropy_event_count = th.device().metrics.entropy_event_count.count();
499501
let entropy_bytes = th.device().metrics.entropy_bytes.count();
500502
let host_rng_fails = th.device().metrics.host_rng_fails.count();
501503
assert_eq!(th.emulate_for_msec(100).unwrap(), 1);

0 commit comments

Comments
 (0)