Skip to content

Conversation

@hawkw
Copy link
Member

@hawkw hawkw commented Jan 13, 2026

Allocation of memory regions (in flash and in RAM) to Hubris tasks is mostly automatic, and the code in cargo xtask sizes that used to tell you a bunch of warnings about suboptimal memory allocations now only does so for the kernel.

However, there is one allocation that is still not done automatically, which is stack sizes. Stack sizes are a bit different from the RAM and flash sizes, as they don't directly impact how the image is laid out in flash or the allocation of memory regions to tasks when the image runs. However, they do sort of impact RAM region sizes, because the stack size limit determines how much of the RAM allocation is used for the image's stack. If the stack limit for a task decreases, it is possible to decrease the size of the RAM allocated to that task, since it needs less RAM for its stack.

It turns out we have a lot of tasks for which the stack limit is substantially larger than the estimated max stack depth produced by cargo xtask sizes. If this means that stacks can actually be made smaller for those tasks, well...
It's Free Real Estate!

It isn't quite that simple, though. For a stack size decrease to actually yield free real estate that can be used by other tasks, it must shrink the RAM allocation for that task by a whole power of two, since memory regions must be power of two sized. Otherwise, we will have just decreased the stack limit without actually freeing up space to be used by other tasks.

Therefore, this branch adds a thingy to cargo xtask sizes that detects potential FREE REAL ESTATE in a hubris image by looking at all the tasks, comparing their currently configured stack limits with the maximum stack depth guessed by get_max_stack, and then checking whether decreasing the stack limit would allow a region allocation shrink. If it would, we yell about it, and track the total amount of potential FREE REAL ESTATE in the image.

For example, app/cosmo/rev-b.toml appears to have in excess of 88 KiB of FREE REAL ESTATE in it, which is a huge amount of RAM:1

eliza@hekate ~/Code/oxide/hubris $ cargo xtask sizes app/cosmo/rev-b.toml
   Compiling xtask v1.0.0 (/home/eliza/Code/oxide/hubris/build/xtask)
    Finished `dev` profile [optimized + debuginfo] target(s) in 3.01s
     Running `target/debug/xtask sizes app/cosmo/rev-b.toml`

...

========== Suggested changes ==========
kernel:
  ram:    6400  (currently 8192)
sys:                                         !!! 1024B of free real estate !!!
  stack    120  (currently 896)
  ram      728  (currently 1504)
spi2_driver:                                 !!! 2048B of free real estate !!!
  stack    440  (currently 872)
  ram     1724  (currently 2156)
spi3_driver:                                 !!! 2048B of free real estate !!!
  stack    440  (currently 872)
  ram     1724  (currently 2156)
rng_driver:                                  !!! 1024B of free real estate !!!
  stack    224  (currently 512)
  ram      788  (currently 1076)
ignition_flash:                              !!! 2048B of free real estate !!!
  stack    400  (currently 1200)
  ram     1884  (currently 2684)
hash_driver:                                 !!! 2048B of free real estate !!!
  stack    984  (currently 2048)
  ram     1180  (currently 2244)
hf:                                          !!! 8192B of free real estate !!!
  stack   1992  (currently 4000)
  ram     7284  (currently 9292)
sensor:                                      !!! 8192B of free real estate !!!
  stack    352  (currently 1024)
  ram     8192  (currently 8864)
udpecho:                                     !!! 7168B of free real estate !!!
  stack    408  (currently 4096)
  ram      772  (currently 4460)
udpbroadcast:                                !!! 3072B of free real estate !!!
  stack    440  (currently 2048)
  ram      892  (currently 2500)
control_plane_agent:                        !!! 32768B of free real estate !!!
  stack   4904  (currently 7000)
  ram    32640  (currently 34736)
sprot:                                      !!! 16384B of free real estate !!!
  stack   3896  (currently 16384)
  ram     9036  (currently 21524)
validate:                                    !!! 2048B of free real estate !!!
  stack    328  (currently 1000)
  ram     1492  (currently 2164)
user_leds:                                    !!! 768B of free real estate !!!
  stack    168  (currently 896)
  ram      236  (currently 964)
snitch:                                      !!! 2048B of free real estate !!!
  stack    256  (currently 1200)
  ram     1648  (currently 2592)
idle:                                         !!! 224B of free real estate !!!
  stack     16  (currently 256)
  ram       16  (currently 256)

there may be up to 91104 bytes of free real estate in this image,
if you're brave enough to mess with stack sizes!

However, there is one big and extremely sketchy thing about just merging the free real estate detector and blindly applying the changes it suggests, which is that I HAVE INVENTED AN EVIL MACHINE THAT TELLS YOU TO ADD STACK OVERFLOWS TO YOUR MISSION CRITICAL FIRMWARE. To wit, the max stack depth estimates are an estimate. As the comment points out:

hubris/build/xtask/src/dist.rs

Lines 1089 to 1092 in aa7951c

/// This does not take dynamic function calls into account, which could cause
/// underestimation. Overestimation is less likely, but still may happen if
/// there are logically impossible call trees (e.g. `A -> B` and `B -> C`, but
/// `B` never calls `C` if called by `A`).

It also may not consider stacks involving panics, if I recall some past trauma correctly. So blindly following the advice from the free real estate detector is probably not a good idea.

I'd like to figure out a good strategy to make it safer, such as allowing the task's TOML to explicitly request some amount of stack over-provision, or to have some "paranoia margin" of, say, 25-50% of the stack size, which we add to the prospective stack shrink before determining whether it would let us do a RAM shrink into a smaller region allocation. Any ideas?

Footnotes

  1. Provided that you have a severe case of embedded brain damage...

@hawkw hawkw changed the title [WIP] bad free real estate detector xtask: bad free real estate detector Jan 15, 2026
@hawkw hawkw marked this pull request as ready for review January 15, 2026 21:56
@hawkw hawkw requested review from cbiffle, labbott and mkeeter January 15, 2026 21:56
Copy link
Collaborator

@labbott labbott left a comment

Choose a reason for hiding this comment

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

(bad free real estate) detector
bad (free real state detector)

Comment on lines +133 to +135
// TODO(eliza): consider also allowing a "bonus stack margin" to be
// requested for paranoia purposes?
let newlim = stack.max_estimate + 8;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not 100% what this is doing , I think this is checking for an 8 byte margin. Could we make that a constant and document that some more?

Copy link
Member Author

Choose a reason for hiding this comment

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

38cb951 added a comment on that, WDYT?

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