Skip to content

Kernel metrics#77

Open
F42J wants to merge 3 commits into
mainfrom
feature/memory-metrics
Open

Kernel metrics#77
F42J wants to merge 3 commits into
mainfrom
feature/memory-metrics

Conversation

@F42J
Copy link
Copy Markdown
Member

@F42J F42J commented May 11, 2026

No description provided.

Copilot AI review requested due to automatic review settings May 11, 2026 20:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a unified, optionally-enabled kernel metrics surface for observing heap allocator usage and per-thread stack usage, wired through the scheduler and HAL stack abstractions.

Changes:

  • Add a new osiris::metrics module exposing global heap, per-task heap, and per-thread stack metrics APIs.
  • Extend the best-fit allocator and Cortex-M stack implementation to track/report allocator and stack usage metrics (behind metrics feature / osiris_metrics cfg).
  • Add build/config plumbing (OSIRIS_DEBUG_METRICS, feature flags, unexpected_cfgs allowlists) to enable metrics across crates.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/sched/thread.rs Adds per-thread stack metrics accessor (cfg-gated).
src/sched/task.rs Adds per-task heap metrics accessor (cfg-gated).
src/sched.rs Adds scheduler entry points to query per-thread/per-task metrics (cfg-gated).
src/metrics.rs New unified public metrics API module.
src/mem/vmm/nommu.rs Exposes AddressSpace allocator metrics (cfg-gated).
src/mem/alloc/bestfit.rs Adds allocator metrics struct/counters, snapshot method, and tests (cfg-gated).
src/mem.rs Adds global heap metrics snapshot helper (cfg-gated).
src/lib.rs Exposes pub mod metrics behind cfg.
presets/stm32l4r5zi_def.toml Adds OSIRIS_DEBUG_METRICS preset env var.
options.toml Adds a debug.metrics option definition.
machine/cortex-m/src/native/sched.rs Adds stack peak tracking + stack metrics implementation + tests (cfg-gated).
machine/cortex-m/Cargo.toml Adds metrics feature and allows cfg(osiris_metrics) in lints.
machine/cortex-m/build.rs Emits cfg(osiris_metrics) when OSIRIS_DEBUG_METRICS is set.
machine/api/src/stack.rs Adds StackMetrics type + default Stacklike::metrics() (cfg-gated).
machine/api/Cargo.toml Adds metrics feature and allows cfg(osiris_metrics) in lints.
machine/api/build.rs Emits cfg(osiris_metrics) when OSIRIS_DEBUG_METRICS is set.
Cargo.toml Adds top-level metrics feature and allows cfg(osiris_metrics) in lints.
build.rs Emits cfg(osiris_metrics) when OSIRIS_DEBUG_METRICS is set.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

peak_offset: 0,
};

stack.push_irq_ret_fn(entry, ctx, fin)?;
Comment on lines +319 to +323
total_bytes,
used_bytes,
free_bytes: total_bytes - used_bytes,
peak_used_bytes: self.peak_offset * word,
}
Comment thread src/metrics.rs Outdated
Comment on lines +3 to +9
//! Enabled by the `metrics` Cargo feature. Provides:
//! - Global heap metrics via [`kernel_metrics`] / [`global_heap_metrics`]
//! - Per-task heap metrics via [`task_heap_metrics`]
//! - Per-thread stack metrics via [`thread_stack_metrics`]
//!
//! For full stack metrics, the backend crate's `metrics` feature must also be
//! enabled (e.g. `hal_cortex_m/metrics`). Without it, stack metrics return zeros.
Comment thread src/mem/alloc/bestfit.rs
use crate::hal::mem::PhysAddr;
let layout =
std::alloc::Layout::from_size_align(length, align_of::<u128>()).unwrap();
let ptr = unsafe { std::alloc::alloc(layout) };
Copy link
Copy Markdown
Member

@thomasw04 thomasw04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Left a few suggestions and comments. Also: please don't use mod.rs anymore, use the new layout like the rest of the codebase.

Comment thread src/mem/alloc/bestfit.rs
/// Head of the free block list.
head: Option<NonNull<u8>>,
#[cfg(any(feature = "metrics", osiris_metrics))]
total_bytes: usize,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a struct AllocatorMetrics?

Comment thread src/sched.rs
/// Called on every reschedule so external readers can access metrics without
/// acquiring the scheduler lock.
#[cfg(any(feature = "metrics", osiris_metrics))]
fn mirror_stats(&self) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating everything here is unnecessary and very costly. On sched_enter there is only one thread and one task that needs an update. The one that was currently running. All other threads/tasks did not change. For now, we ignore multi-core/SMP systems.

Comment thread src/metrics/mod.rs
/// Returns the latest global kernel heap snapshot, or `None` if the scheduler
/// has not yet run a single reschedule.
pub fn global_heap() -> Option<HeapSnapshot> {
store::read_global_heap()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think store::global_heap() would be a better name, as it's more consistent with the rest of the codebase. Same for the other functions.

Comment thread build.rs
println!("cargo::rerun-if-changed=build.rs");
println!("cargo::rerun-if-env-changed=OSIRIS_DEBUG_METRICS");
if std::env::var("OSIRIS_DEBUG_METRICS").map_or(false, |v| v == "true" || v == "1") {
println!("cargo::rustc-cfg=osiris_metrics");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other cfg's do not have the osiris_ prefix. I think calling it "metrics" here is fine.

Comment thread src/mem/alloc/bestfit.rs
/// Snapshot of allocator resource usage. Available when the `metrics` feature is enabled.
#[cfg(any(feature = "metrics", osiris_metrics))]
#[derive(Debug, Clone, Copy)]
pub struct AllocatorMetrics {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put this struct directly in alloc.rs and name it Metrics (alloc::Metrics), as these metrics should be relevant for all types of allocators.

Comment thread src/mem/alloc/bestfit.rs
}

#[cfg(any(feature = "metrics", osiris_metrics))]
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest creating then functions in the Metrics struct, such as "record_alloc" that you then just call from all tracing points.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants