Skip to content

fix(developer-rust): defer CPU by nice and weight, drop the build semaphore - #91

Merged
catinspace-au merged 1 commit into
mainfrom
fix/rust-governor-cpu-last
Sep 7, 2026
Merged

fix(developer-rust): defer CPU by nice and weight, drop the build semaphore#91
catinspace-au merged 1 commit into
mainfrom
fix/rust-governor-cpu-last

Conversation

@catinspace-au

Copy link
Copy Markdown
Contributor

The governor was protecting the host three ways at once and two of them were pure throughput loss. A 2-core reserve came off the top, then the memory semaphore divided what was left by the slots it would admit, and a 32-core box built at -j3. Yielding was the only one of the three we wanted.

What changes

  • builds run at nice 19 inside rustbuild.slice. No core withheld, no job count set, cargo's default is every core
  • the semaphore, the reserve, the lock wait, the degrade path and the -j arithmetic are gone from the shim: 411 lines to 100. Their five role variables now FAIL the converge with a message rather than being ignored, so a host that thinks it has one build at a time finds out
  • the slice is renamed from rust-build.slice. The dash put it under an auto-created rust.slice where its CPUWeight had no sibling to compete with, so the weight never reached the desktop -- checked on the cgroup tree here. The old unit is removed at converge
  • the shim probes the user bus before it execs, so a stale /run/user in a container falls back to plain nice instead of failing every cargo
  • hyperi-sccache.service gets Nice=19 beside Slice=, because compiles run inside the server and inherit nothing from cargo
  • macOS gets nice 19 too. taskpolicy and its QoS knob go -- one mechanism on every OS
  • first tests for the shim: tools/tests/test_rust_govern.py, ten cases on the no-bus path so they run anywhere

What the docs now say honestly

  • CPUWeight is what makes a build yield on Linux, and it binds against app.slice inside the user manager. It does NOT reach another ssh session (a sibling of the whole user manager). A weight on user@UID.service would, and that is a system unit -- your call whether we want it
  • nice 19 orders the build against whatever shares its cpu cgroup and nothing beyond, which is the desktop on a box with no cpu delegation and nothing much on one with it
  • a 16 GB laptop gives the slice 11.2 GB and one rustc has been measured at 11.6 GB. That build dies with cargo reporting signal 9. The doc says so and names the levers

Not done here

  • Fedora/Ubuntu snapshot VMs: converge, check systemctl --user show rustbuild.slice -p CPUWeight reads 30, reset
  • the Mac side by hand
  • nothing installed on the desktop was touched, the live builds were running. Once converged, delete ~/.config/rust-build-env.sh and its .bashrc line -- the exports it carried are now the defaults

Done when a stock SOE Rust box builds at full core count and yields under contention, with no per-machine tuning and nothing for a second session to keep in sync.

Supersedes #78. Closes #90.

…aphore

The governor was rationing CPU three ways at once and two of them were pure
throughput loss: a 2-core reserve, then the core pool divided by a memory
semaphore's slot count. On a 32-core box that settled on -j3.

- builds now run at nice 19 inside rustbuild.slice, no core withheld, no job
  count set, cargo's own default is every core
- the semaphore, the reserve, the lock wait, the degrade path and the job
  arithmetic are gone from the shim (411 -> 100 lines), and their five role
  variables fail the converge with a message rather than being ignored
- the slice is renamed from rust-build.slice: the dash put it under an
  auto-created rust.slice where its CPUWeight faced no sibling, so the weight
  never reached the desktop. The old unit is removed at converge
- the shim probes the user bus before the exec, so a stale /run/user falls
  back to plain nice instead of failing every cargo
- hyperi-sccache.service carries Nice=19 as well as the slice, because compiles
  run inside the server and inherit nothing from cargo
- macOS gets nice 19 too; taskpolicy and its QoS knob go
- the shim gets its first tests: tools/tests/test_rust_govern.py

Docs say what each instrument actually reaches: the weight binds against
app.slice inside the user manager, not against another ssh session, and nice
orders the build against whatever shares its cpu cgroup and nothing beyond.

Supersedes #78: there are no slots left to weight.

Closes #90
@catinspace-au
catinspace-au merged commit 621f2e1 into main Sep 7, 2026
16 checks passed
@catinspace-au
catinspace-au deleted the fix/rust-governor-cpu-last branch September 7, 2026 22:03
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.

Rust builds should get the CPU last, not fewer cores

1 participant