From 07faaf83870bce1f63b3261a91dffec7e7baa21f Mon Sep 17 00:00:00 2001 From: Alan Hanson Date: Mon, 9 Mar 2026 11:30:11 -0700 Subject: [PATCH 1/3] Metrics for disks --- lib/propolis/src/block/attachment.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/propolis/src/block/attachment.rs b/lib/propolis/src/block/attachment.rs index 4805ea1b5..f7291d64f 100644 --- a/lib/propolis/src/block/attachment.rs +++ b/lib/propolis/src/block/attachment.rs @@ -26,19 +26,19 @@ use std::task::{Context, Poll}; use super::minder::{NoneInFlight, QueueMinder}; use super::{ - devq_id, probes, BackendId, DeviceId, DeviceInfo, DeviceQueue, - DeviceRequest, MetricConsumer, QueueId, WorkerId, + BackendId, DeviceId, DeviceInfo, DeviceQueue, DeviceRequest, + MetricConsumer, QueueId, WorkerId, devq_id, probes, }; use crate::accessors::MemAccessor; use crate::block; -use futures::stream::FuturesUnordered; use futures::Stream; +use futures::stream::FuturesUnordered; use pin_project_lite::pin_project; use strum::IntoStaticStr; use thiserror::Error; -use tokio::sync::futures::Notified; use tokio::sync::Notify; +use tokio::sync::futures::Notified; pub const MAX_WORKERS: NonZeroUsize = NonZeroUsize::new(64).unwrap(); @@ -127,10 +127,11 @@ impl QueueSlot { } } -#[derive(Default, Copy, Clone)] +#[derive(Default, Clone)] struct QueueColState { associated_qids: Versioned, paused: bool, + metric_consumer: Option>, } impl QueueColState { fn queue_associate(&mut self, qid: QueueId) -> Versioned { @@ -177,8 +178,10 @@ impl QueueCollection { slot.flush_notifications(); } fn set_metric_consumer(&self, consumer: Arc) { + let mut state = self.state.lock().unwrap(); + state.metric_consumer = Some(consumer.clone()); for queue in self.queues.iter() { - if let Some(minder) = queue.state.lock().unwrap().minder.as_mut() { + if let Some(minder) = queue.state.lock().unwrap().minder.as_ref() { minder.set_metric_consumer(consumer.clone()); } } @@ -256,7 +259,7 @@ impl QueueCollection { cursor: &mut PollCursor, wid: WorkerId, ) -> Option { - let idx = usize::from(cursor.0 .0); + let idx = usize::from(cursor.0.0); assert!(idx < self.queues.len()); let (front, back) = self.queues.split_at(idx); let queues = back.iter().chain(front.iter()); @@ -517,6 +520,11 @@ impl DeviceAttachment { // associating queues while in such a pause. minder.pause(); } + if let Some(consumer) = state.metric_consumer.as_ref() { + // Propagate any metric consumer already registered with + // this device to the newly-associating queue. + minder.set_metric_consumer(consumer.clone()); + } slot_state.minder = Some(minder); drop(slot_state); From 8a0026763144cb18f1a23fadecd4527602503df0 Mon Sep 17 00:00:00 2001 From: Alan Hanson Date: Mon, 9 Mar 2026 18:34:36 +0000 Subject: [PATCH 2/3] fix cargo fmt --- lib/propolis/src/block/attachment.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/propolis/src/block/attachment.rs b/lib/propolis/src/block/attachment.rs index f7291d64f..88bdca6bb 100644 --- a/lib/propolis/src/block/attachment.rs +++ b/lib/propolis/src/block/attachment.rs @@ -26,19 +26,19 @@ use std::task::{Context, Poll}; use super::minder::{NoneInFlight, QueueMinder}; use super::{ - BackendId, DeviceId, DeviceInfo, DeviceQueue, DeviceRequest, - MetricConsumer, QueueId, WorkerId, devq_id, probes, + devq_id, probes, BackendId, DeviceId, DeviceInfo, DeviceQueue, + DeviceRequest, MetricConsumer, QueueId, WorkerId, }; use crate::accessors::MemAccessor; use crate::block; -use futures::Stream; use futures::stream::FuturesUnordered; +use futures::Stream; use pin_project_lite::pin_project; use strum::IntoStaticStr; use thiserror::Error; -use tokio::sync::Notify; use tokio::sync::futures::Notified; +use tokio::sync::Notify; pub const MAX_WORKERS: NonZeroUsize = NonZeroUsize::new(64).unwrap(); @@ -259,7 +259,7 @@ impl QueueCollection { cursor: &mut PollCursor, wid: WorkerId, ) -> Option { - let idx = usize::from(cursor.0.0); + let idx = usize::from(cursor.0 .0); assert!(idx < self.queues.len()); let (front, back) = self.queues.split_at(idx); let queues = back.iter().chain(front.iter()); From e42f6e5632a6975aca486a4efe7d1b86abe6dd64 Mon Sep 17 00:00:00 2001 From: Alan Hanson Date: Wed, 11 Mar 2026 13:41:46 -0700 Subject: [PATCH 3/3] Move clone after loop --- lib/propolis/src/block/attachment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/propolis/src/block/attachment.rs b/lib/propolis/src/block/attachment.rs index 88bdca6bb..4842abfbb 100644 --- a/lib/propolis/src/block/attachment.rs +++ b/lib/propolis/src/block/attachment.rs @@ -179,12 +179,12 @@ impl QueueCollection { } fn set_metric_consumer(&self, consumer: Arc) { let mut state = self.state.lock().unwrap(); - state.metric_consumer = Some(consumer.clone()); for queue in self.queues.iter() { if let Some(minder) = queue.state.lock().unwrap().minder.as_ref() { minder.set_metric_consumer(consumer.clone()); } } + state.metric_consumer = Some(consumer); } fn associated_qids(&self) -> Versioned { self.state.lock().unwrap().associated_qids