sched: the expected-end estimates walk the whole queue after every pass (250 to 380 ms a round, a fifth of the scheduler's thread, which is at its ceiling when CI places jobs) #53
Open
opened 2026-11-13 04:35:34 +00:00 by xemmerling
·
0 comments
No Branch/Tag specified
main
dev/schema-step-order
t-join-release
t-work-booking
t-ahead-deadlock-wip
t-hotfix-9ae
t-width-work
t-id-token-renew
t-claim-unkept
t-resume-live
t-run-record
t-all-lockfiles
t-relay-offset
t-blame-event
t-freer-links
t-load-tests
t-jobserver2
t-starved-timeout
t-client-pack
t-offline-config
t-test-plan
t-told-resume2
t-jobserver
t-told-resume
t-outbound2
t-crash-open-bench
t-told-once
guest-never-below-given
admit-page-cache-active
pooled-admission
driver-give-back
no-sizes
one-driver-per-check
archive/vm-root-share
archive/build-out-kept
archive/cargo-perf
archive/virtiofs-readdir-alloc
archive/vm-outputs-stream
archive/stable-verify-priority
archive/agents-1
archive/stack-parallel
archive/cpu-admission
archive/narrow-from-every-log
archive/old-t
archive/worker-store-gc
archive/failing-builds-kept
archive/vm-cargo-home
archive/lifecycle
archive/bench-own-cores
archive/place-test-binaries-nocopy
archive/vm-net-upload-stall
archive/booking-current-use
archive/archive-dep-out-dirs
archive/any-arch-shards
archive/prepare-stall-progress-ns20
archive/s2
archive/next-set-20
archive/store-full-waits
archive/fetch-caps-by-node
archive/vm-step-phases
archive/arm-only-for-arm
archive/deploy-all-workers
archive/lifecycle-staging
archive/lifecycle-1-wire
archive/fast-gate
archive/cargo-key-narrow
archive/log-leads-followup
archive/gate-limit
archive/prepare-stall-vm-bytes
archive/lifecycle-2-ends
archive/cache-hits-bind
archive/failing-reused
archive/oci-archive-direct
archive/prepare-stall-progress
archive/test-quarantine
archive/crash-safe-on-18
archive/build-script-etxtbsy
archive/old-release
archive/next-set-19c
archive/wait-reasons
archive/cache-put-best-effort
archive/hang-not-t-time
archive/shard-test-results
archive/vm-carry-on-17
archive/check-test-filter
archive/artifact-path-beneath
archive/stall-room-xfs
archive/build-dir-no-recopy
archive/cache-hits-link
archive/outputs-no-follow-on-copy
archive/outputs-no-follow
archive/next-set-19
archive/hang-detect
archive/stable-verify-stable-plan
archive/freer-target-only
archive/lease-pricing-narrow
archive/vm-outputs-once
archive/queue-place-starved
archive/publish-reads
archive/disk-warning-scratch
archive/outputs-no-copy
archive/wd-probe-3min
archive/watchdog-on-d65
archive/log-leads-with-excerpt
archive/queue-place
archive/prep-watchdog-progress
archive/cache-put-stack-room
archive/cache-put-stack
archive/place-by-pace
archive/nested-sync-helper
archive/next-set-18y
archive/archive-bins-by-env-19
archive/next-set-18
archive/disk-want-held
archive/young-booking-back
archive/flaky-tests-1027b
archive/next-set-17
archive/prep-start-at-close
archive/unpack-error-on-17
archive/server-memory-high
archive/vm-start-held
archive/vm-carry-on-14
archive/space-trim-registry-room
archive/file-cache-ns16
archive/unpack-error-final
archive/crash-safe-worker
archive/server-space-trim
archive/status-big-runs
archive/nested-tmp-volatile
archive/publish-refresh
archive/gc-cache-quiet-reads
archive/next-set-16
archive/vm14-proof
archive/csw-node-kill
archive/unpack-link
archive/vm-tests-15
archive/seccomp-allow-field
archive/flaky-tests-1027-ns15
archive/shard-fail-fast
archive/server-node-check
archive/live-log-restart
archive/unpack-no-orphans
archive/flaky-tests-1027
archive/fetch-share-images
archive/fetch-images-red4
archive/forget-cached
archive/put-file-once-ns15
archive/recheck-rank-15
archive/fetch-images-red3
archive/unpack-no-orphans-red2
archive/fetch-io-pass-followups
archive/sandbox-no-fallback-ns15
archive/unpack-no-orphans-red
archive/archive-bins-by-env-ns15
archive/ns15-proof
archive/next-set-15
archive/archive-bins-by-env
archive/vm-guest-panic-15
archive/sandbox-no-fallback
archive/recheck-rank
archive/placement-ahead-bound
archive/carry-keeps-listing
archive/registry-parallel-pull
archive/sandbox-tests-15
archive/attempt-log-live-15
archive/follow-progress-16
archive/follow-progress-15
archive/ns15-archive-base
archive/fetch-io-max-on-13
archive/fetch-images-red2
archive/transient-build-fail-15
archive/test-ended-early-15
archive/archive-keep-cleanup
archive/main-merge-14
archive/sandbox-clone3-fallback
archive/vm-carry-on-13
archive/fetch-io-sweep-15
archive/vm-root-disk-fixes
archive/vm-guest-panic
archive/follow-progress-14
archive/archive-keep-on-demand
archive/vm-exit-unseen
archive/file-cache-share
archive/bwrap-root-userns
archive/transient-build-fail
archive/fetch-io-max
archive/file-cache-guard-11
archive/fetch-io-sweep
archive/archive-build-dir-skip
archive/next-set-14
archive/wrapper-one-read
archive/archive-tmp-links
archive/attempt-log-live
archive/fetch-share-and-order
archive/vm-hang-io-wait
archive/vm-carry-fixes
archive/image-cancel
archive/test-ended-early
archive/sim-on-train3-bundle
archive/hits-layer-wip
archive/t-old-putfile
archive/archive-links
archive/stall-on-13
archive/carried-prep-completes
archive/put-file-once
archive/preview-14
archive/follow-progress
archive/gc-reads-dont-protect
archive/admission-replay-people
archive/people-pickup
archive/gc-pass-visible
archive/hits-layer
archive/own-build-priced
archive/compact-stamps-followup
archive/prepare-timing
archive/sim-on-train3
archive/next-set-13
archive/next-set-12b
archive/sim-on-next-set-12
archive/deploy-doc-no-kill
archive/next-set-12
archive/attempt-logs-real
archive/sim-tests-green
archive/shard-label-index
archive/young-booking
archive/next-set-11
archive/data-dir-config-env
archive/vm-sync-not-host-store
archive/attempt-logs
archive/wrapper-ro
archive/tests-wait-on-events
archive/blame-git-optional-needs
archive/job-file-headroom-impl
archive/next-set-10
archive/blame-verdict-fresh-parent
archive/compact-touched-stamps
archive/interactive-incremental-off
archive/follow-lost-lines-counted
archive/evict-test
archive/next-set-trial
archive/keys-cover-output-bytes
archive/file-cache-guard
archive/blame-after-parent
archive/test-filter-matching-nothing-fails
archive/s1-on-d96
archive/draining-node-queues
archive/tprev-checks-prod-next
archive/s1-dead
archive/follow-live-run
archive/guard-stopped-setup-text
archive/io-error-cause
archive/source-layer-whole
archive/clippy-groups
archive/worker-silence-grace
archive/price-touched
archive/prod-next
archive/batch1
archive/s1-on-prod-next
archive/vmcache/sandbox-copyup-pin
archive/s1-xfs-store
archive/warm-script-builds
archive/vmcache/setup-tag-digest
archive/vmcache/setup-should-fixes
archive/vmcache/setup-any-arch
archive/guard-livelock
archive/host-budget
archive/wire-format-test
archive/admission-replay
archive/switch-safe
archive/stall-window
archive/upgrade-carries-preparing
archive/static-init
archive/switch-proof-b
archive/carry-tokens
archive/seals-together
archive/switch-safe-storage
archive/switch-safe-worker
archive/batch-b-prev
archive/vmcache/batch-b
archive/carry-vm-helpers
archive/small-llvm-args-failed-log
archive/batch-a
archive/stall-hotfix
archive/prev-pacing
archive/u-try-wip
archive/u-try
archive/u-try-wip2
archive/flatten-verify
archive/poll-free
archive/flatten-tiers
archive/hotfix-cross
archive/pool-stall
archive/disk-pacing
archive/u-builds-from-graph
archive/mac-idle
archive/ship-direct
archive/vmcache/shards
archive/soft-margin
archive/behind-no-target
archive/filtered-binaries
archive/vmcache/setup-layers
archive/direct-off-prev
archive/probe-budget
archive/vm-helper-exit
archive/jobs-soft-bound
archive/vmcache/vm-disks
archive/vmcache/failure-outputs
archive/narrowed-not-verdict
archive/scratch-direct-off
archive/handover-holds
archive/memory-lines
archive/drain-destroys
archive/pool-size
archive/drain-own-frees
archive/test-schema-drop
archive/deploy-disk
archive/deploy-disk-lines
archive/clone-aware-freeing
archive/absolute-headroom
archive/zfs-pool-size
archive/u-int5
archive/u-load
archive/u-warn
archive/u-steer
archive/revert-stall-once
archive/guard-headroom
archive/u-int3
archive/u-readsets
archive/u-hermetic
archive/mem-virtio
archive/u-buildjobs
archive/u-waits
archive/u-three
archive/u-zfs-stall
archive/u-config
archive/u-lean
archive/u-e2e
archive/u-integrate2
archive/u-jobenv
archive/u-cache-blobs
archive/u-observe2
archive/u-sched-nospread
archive/u-node-bound
archive/u-sched-oom
archive/u-review-store
archive/u-observe
archive/u-review-engine
archive/u-review-srv
archive/u-review-node
archive/u-review-sched
archive/preempt-measured
archive/u-integrate
archive/u-eng
archive/lock-off-runtime
archive/u-vm
archive/u-gone
archive/u-offline
archive/ready-starve
archive/u-notices
archive/heads-never-superseded
archive/u-learn
archive/int
archive/u-graph
archive/u-umount
archive/supersede-followed
archive/preparing-booking
archive/u-xdev
archive/u-env
archive/u-poll
archive/u-wrap
archive/u-room
archive/u-wrap-try
archive/u-fixed
archive/unstall
archive/u-fix3
archive/u-cwd
archive/resume-supersedes
archive/server-heap
archive/u-harness
archive/u-macos
archive/u-node
archive/u-eng2
archive/u-leader
archive/u-cutover
archive/u-cache
archive/u-sched
archive/u-engine
archive/chore/agpl-license
archive/note-x86-disk-room
archive/pass-cost
archive/prod-defects
archive/clippy-false-greens
archive/t-pace-variance-prototype
archive/outputs-reattach
archive/fix-retry-needs
archive/no-supersede-uncached
archive/fix/promoted-view-mtime
archive/rb-merge
archive/ft-sched
archive/ft-node
archive/ft-engine
archive/fx-sim
archive/fx2-mem
archive/fx2-store
archive/fx2-ci
archive/fx-work
archive/fx-ci
archive/fx-sched
archive/fx-req
archive/fx-store
archive/fx-cache
archive/rb-storage
archive/rb-scheduling
archive/rb-sweep
archive/rb-tracking
archive/rb-workers
archive/rb-client
archive/rb-profiles
archive/rebuild
archive/batch-deploy
archive/fix-roll
archive/work
archive/fix-busy
archive/fix-perf
archive/fix-suite
archive/fix-spread
archive/fix-sig
archive/fix-wait
archive/fix-init
archive/sizing
archive/fix-drift
archive/delivery
archive/fix-snap
archive/fix-own
archive/fix-rollout
archive/fix-hang
archive/fix-tree
archive/images
archive/fill
archive/sched-gate-preparing-after
archive/takeover-sim
archive/image-d244b22
archive/image-ce8a09e
archive/image-c9ff4f7
archive/image-489bec9
archive/image-7e07ffb
archive/image-583ea93
archive/image-8e1cd2c
archive/image-fbf0a9c
archive/image-6924e11
archive/image-29cabc3
archive/image-97ebb0e
archive/image-d0e23ac
archive/image-319fce9
archive/image-4f689e1
archive/image-feacbcd
archive/image-d5d9446
archive/image-6b86940
archive/fix/dedup-priority-promotion
archive/image-a5b0fe3
archive/image-462afb1
archive/image-f39d42c
archive/image-6e71fb4
archive/image-0c62329
archive/resources
archive/image-112b6a6
archive/image-8b06530
archive/image-5ae7cd8
archive/fmt-fix-in-t-toml
archive/image-arm64
Labels
Clear labels
No items
No labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
tilo/t#53
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Update 13:37Z 2026-11-13: the hour after the 12:32Z restart (
f06bfdc3). Passes over a second, from the server's own warnings:Weighing was 3.1 to 3.3 s of a 3.5 s pass at 12:39Z (45,311 asks, no grows). Over the whole hour the mean pass was 1.47 s and passes took 77% of the thread. So for about forty minutes after a restart the long passes are the rule, with the same number of asks that later pass in under two seconds: the weighing is slower while the runs driven again are still placing, not because the queue is longer. On
8210a6d7before it, 90 minutes stayed under a 2.25 s mean.Update 08:12Z 2026-11-13 (
ebbad1e3, then0f37ba87from 08:04Z). The pass time is bimodal, which the means below hide. Fromt_pass_seconds_bucket, production only:ebbad1e30f37ba87a scheduling pass took long, 08:07 to 08:10Z) run 3.0 to 4.8 s at 45,000 asks, with weighing 3.1 to 4.5 s of it andpredict0.2 s.State::passhas no early end: every pass walks the whole line. So the two modes differ in whatdecidecosts for one ask, about 10 µs in a short pass and about 80 µs in a long one.dbbcad6adid not change this: mean pass by minute after the restarts at 06:01Z, 07:04Z and 08:04Z climbs alike to 1.2 to 1.7 s as the queue refills to 45,000.Update, 2026-11-13 06:26Z, on
21edb1e8. The pass has been at about 1.5 s since 06:09Z, steadily, and the thread is full.State::pass, mean msa scheduling pass took long) fired 188 times in the 15 minutes to 06:24Z, about every pass. The longest: 4.8 s at 06:14:00Z, of it 4.3 s weighing 44,289 asks (1.5 s of that resolving one driver's graph); four more between 3.9 and 3.6 s.86fa55c0and 19 at 04:31Z. It is highest while CI places nothing: people's sessions hold the node, so every pass weighs 44,000 CI asks that are each short by one core and places none of them.So beside the estimates, the larger part is the weighing of asks that cannot fit: a pass that knows a node has no core left for a class still decides each of that class's asks for that node.
Seen on t.tilo.so on 2026-11-13, on
d26adb93and on86fa55c0before it. A proposal with its measurements; the module is the scheduler's owner's, so nothing is patched from my side.The scheduler's one thread is at its ceiling whenever CI places jobs. Of each second it spends (Prometheus,
t_pass_secondsandt_pass_phase_seconds, ten-minute rates, production only):State::passmspredictms86fa55c086fa55c0eeb2996ad26adb93d26adb93t_pass_secondstimesState::passalone. After it the thread makes the view and thenview.eta = self.state.predict(now)(src/sched/mod.rs). Pass, view and predict together took about 90% of the thread at 02:20 to 02:40Z and about 97% at 04:30Z; a round takes about 1.4 s there, and the scheduler decides 0.7 times a second where it decided 1.3.State::predict(src/sched/state/eta.rs) gives each running job an expected end and then walks the whole line again (forward): for every queued ask it works out what admission would ask and the first node and moment it would fit. That is a second weighing of the queue after every pass, 250 to 380 ms a round, a fifth to a quarter of the thread.server/pages/now.rs,server/pages/run.rs) and the views' per-run estimate (runs/mod.rs,Kept::begin). No placement reads it: admission readsState::end_offor running jobs throughState::counted, which a pass calls itself.Proposed, for the owner to judge: work the estimates out less often than every pass (every few passes, or at most once in some seconds), or off the scheduler's thread from a copy of its state. Nothing but the freshness of the pages' expected ends would change, and the thread gets a fifth to a quarter of its time back for passes.
Not shown: that the pass cost limits CI's job starts today. People's jobs start within 3 s at the 95th percentile throughout.
Relay messages to the scheduler's owner go to an inbox that has been offline since 2026-11-12 10:31Z, so this is filed here.
11-13, production on
9faf6c61(65bf0d9blive since 16:32Z), no restart in the window: the mean pass over five minutes (t_pass_seconds_sum / _count) ran 1,130 to 1,670 ms from 17:26 to 18:01Z, 2,046 ms at 18:06Z, 2,183 ms at 18:51Z and 2,583 ms at 18:56Z, with 73 to 83% of the thread inside passes and the passes per five minutes falling from 198 to 96. Queued asks stayed 43,300 to 46,500, so this is not the queue growing. The passes the server logs as long: 91 to 119 per ten minutes since the 16:32Z restart at 3.2 to 3.5 s (70 to 85 per ten minutes at 3.4 s on the build before), the longest 7.97 s at 18:32:35Z (pass=6.96 weighing=4.98 predict=0.85 asks=43497 resolves=7). The database was at 9% throttled periods at 18:56Z, so it does not explain that reading. Since65bf0d9bthe server also logged "a job placed on a node without room for it ... held there" 84 times in two bursts right after the restart and a handful since, against about one an hour before; no wait came of it.19:01Z 11-13, the placement warning outside a restart: 150 lines "a job placed on a node without room for it ... held there" within 48 s (141 in one minute), 144 jobs on the worker, each
why="every start under way"with busy 157 to 189 of a budget of 159. It was a wave from people's sessions: 317 people's jobs were handed in the minute before, and 137 of the 144 held were people's. Each waited 0.17 s at the median and 0.8 s at most from handed to started, so nothing came of it but the lines; before65bf0d9bthere was about one such line an hour.20:40Z 11-13, the pass keeps lengthening with no restart and a nearly level queue. Mean pass over five minutes 3,569 ms with 88% of the thread inside passes (three-minute means since 20:00Z: 1.6 to 3.7 s, thread 77 to 91%); queued asks 48,300 to 49,600; the server at 4.4 to 5.6 cores against 3.0 to 3.4 this afternoon. From the long-pass lines:
Weighing (the queued jobs weighed) is nine tenths of a pass and rose 46% while the queue rose 14%: 60 to 78 microseconds an ask. So something beside the queue's length scales it. What differs this evening is people's sessions: 39 to 52 of their jobs out at a time and 400 to 900 starts a quarter hour, with people's jobs taking 90% of the node's CPU from 19:58 to 20:28Z. People's pickup p95 moved from 4.0 to 4.7 s; nothing else has come of it yet. At 92% of the thread I expect placement to lag for everyone.
The trend over 24 hours (
t_pass_seconds,t_pass_phase_seconds{phase="weighing"}, two-hour means over all passes):The queue grew by half in the day and the weighing by seven times, so the cost of weighing one queued ask more than quadrupled: it grows with something else as well (open head runs went from about 150 to 305 in the same day, and the claims the server holds stand at 400,000 keys with 453,000 waiters). At this slope the scheduling thread is saturated within a day or less.
23:44Z 11-13, on
6ebaa239(your promote of 22:08Z): the same picture. Ten-minute means:The restart took the queue to about 40,000 and it is at its highest yet again an hour and a half later, with 345 heads open. Neither of my marks (a mean pass of 5 s, 92% of the thread) was passed.
00:40Z 11-14, on
c2d52b34: every pass takes 3 to 4 s, and the node dipped under 130 busy cores with a full queueFrom the server's own "a scheduling pass took long" lines since it started at 00:22Z, averaged per two minutes:
views after a passholds a runtime thread 0.5 to 0.8 s each time: 2,182 such warnings in the server's first 18 minutes.startsfor 398 s and bycoresfor 277 s of those 20 minutes (t_node_line_held_seconds_total).My reading, not shown: with passes of 3.5 s the node is refilled once per pass, so a burst of short jobs ending leaves cores booked but idle until the next pass, and the starts allowed at once cap what one pass can put back. Nothing here is mine to patch; it is data for the planner.
02:47Z 11-14, on
c2d52b34: the mean pass is past five secondsMy watch's mark was a five-minute mean of 5,000 ms. It read 5,375 ms at 02:47Z, with 90% of the thread inside passes. The two 90-minute watches before it ended at 4,055 ms (highest 4,415) and 4,248 ms (highest 4,761).
From the server's own "a scheduling pass took long" lines, averaged per two minutes:
views after a passheld a runtime thread 194 times in the 16 minutes. No "ran its tasks late" line.startsfor a few seconds a minute at most.Update 11:20Z 2026-11-14: the weighing follows people's starts, not the queue (
58b70474and the builds before it).t_pass_phase_secondsby phase, ten-minute means, with the queue between 65,000 and 74,000 asks throughout: