Skip to content

WIP: Kernel accounting of task CPU usage - #2592

Draft
jamesmunns wants to merge 3 commits into
james/unsafe-tweaksfrom
james/hutop
Draft

WIP: Kernel accounting of task CPU usage#2592
jamesmunns wants to merge 3 commits into
james/unsafe-tweaksfrom
james/hutop

Conversation

@jamesmunns

Copy link
Copy Markdown
Contributor

This is currently "minimum viable experiment" state, it did work while testing, but I was distracted by discovering #2588 while implementing this.

@jamesmunns

Copy link
Copy Markdown
Contributor Author

Oh, and there are a bunch of semi-unrelated changes/refactoring to kernel unsafe code that I should probably factor out into a separate PR, or revert. I was mostly just putzing around while looking at things understanding how scheduling and startup worked in process.

@cbiffle you might be interested in these, outside of the context of time accounting.

@jamesmunns

Copy link
Copy Markdown
Contributor Author

Misc note, this PR (and #2571 before it) uses the hardware system timer at 1MHz resolution. However, there is practically little downside IMO for this use case to not use the maximum possible speed, 200MHz (the full speed of the APB1 timer clock) for ticking.

With a 32-bit timer, this would roll-over every 21.47 seconds, meaning that as long as we perform "timekeeping" every 10.73 seconds, this frequency is suitable. One potential risk is if a debugger causes the core to be halted longer than that, we may observe "weird" time (potentially breaking monotonic guarantees). At 1MHz, this is 200x longer, meaning our max acceptable interruption time is roughly 35.79 minutes.

With a 64-bit extended timing range at 200MHz, we would have a full range of 2922 years before encountering a roll-over. It seems acceptable to qualify this as "forever", as it is likely we will not experience that duration of uptime. If we are concerned about this, we could operationally require a reboot every two millennia or so for good measure.

This increased precision would allow for fewer rounding errors when calculating time spent in each task. At 1MHz, I'd say our practical resolution is compromised when there is less than 2us between scheduling operations, which is approximately 800 CPU cycles. It is probably not THAT often we are scheduling a task for less than that time, but it does seem at least potentially possible. There is probably some floor to this: whatever our total time spent entering and exiting a task, e.g. one that immediately yields or is interrupted, probably measured in the dozens-to-low-hundreds of cycles. For this, even bumping up to 10(s) of MHz is likely "good enough", even if we don't go all the way up to 200MHz.

One downside of not picking 1MHz as "the official timebase" is potential variance in precision between targets. The LPC55 likely can't run a timer all the way up to 200MHz. That being said, the current impl can handle this reasonably.

@labbott labbott left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Some of this is good cleanup which might be good to review/merge separately.

Comment thread drv/stm32h7-startup/Cargo.toml Outdated
Comment thread sys/ptime/src/lib.rs
Comment thread sys/kern/src/startup.rs
Comment thread sys/kern/src/task.rs Outdated
@jamesmunns
jamesmunns changed the base branch from master to james/unsafe-tweaks July 20, 2026 07:46
@jamesmunns

Copy link
Copy Markdown
Contributor Author

Rebased on top of #2600, and set that as the base merge target to make the diff more clear.

@jamesmunns

Copy link
Copy Markdown
Contributor Author

There are a couple of targets that are failing:

  • some sidecar targets, which currently have a smaller kernel RAM/Flash allowance than other cosmo/gimlet boards. I'm guessing this isn't intentional, and we can probably bump these somewhat freely
  • some stm32g0 targets. These might be able to be bumped up to the necessary size, but also raises the question whether this should be a toggle-able feature, as it requires TASKS * size_of(u64) additional RAM, which isn't a ton, but everything is a lot when you don't have very much

I can think of two ways to gate this:

  • use the existing kernel "nano" feature, disable the ptime stuff when it is active. This would gate things out for I think all of the stm32g0 targets, which already use "nano".
  • Introduce a new "ptime" feature in the kernel. We can either make this an active-by-default feature (and opt-out in stm32g0 apps), or NOT make it default, and make all apps that want it opt-in. Either of these options is going to touch a lot of manifests.

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.

2 participants