Skip to content

cpu: map pod CPU QoS onto cocoon cgroup knobs, read scope-based stats - #67

Merged
CMGS merged 5 commits into
mainfrom
cpu-cgroup-qos
Aug 5, 2026
Merged

cpu: map pod CPU QoS onto cocoon cgroup knobs, read scope-based stats#67
CMGS merged 5 commits into
mainfrom
cpu-cgroup-qos

Conversation

@CMGS

@CMGS CMGS commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Why

cocoon now spawns every VMM into a per-VM cgroup v2 CPU scope with Guaranteed-at-N defaults (cocoonstack/cocoon#183) and a host-level cpuset fence (cocoonstack/cocoon#185). Two consequences for vk-cocoon:

  • The vCPU count vk passes is now a hard cap. vk derived it from requests (rounded up), so a burstable pod (requests: 500m, limits: 2) would get hard-capped at 1 core after the node upgrade — K8s semantics inverted.
  • All clone paths passed no CPU policy at all, and cocoon deliberately never inherits cgroup knobs from snapshots — every cloned/woken pod would run at defaults regardless of its pod resources.

What

  • Run path: vCPU and --cpu-quota-us bound at the pod's CPU limit (requests only as fallback when no limit); --cpu-weight derived from requests via kubelet's cgroup v2 shares→weight conversion, so contention shares match what kubelet grants the same pod. --cpu-period-us is passed alongside the quota so the conversion never drifts from cocoon's default period.
  • Clone paths (fromDir, forkFrom, default clone, hibernate wake): the same pod-derived policy is passed via the new shared vm.CPUPolicy embedded in RunOptions/CloneOptions.
  • Stats: per-VM CPU seconds now read from the VM scope's cpu.stat usage_usec (includes virtio/io_uring kernel workers that /proc/<pid>/stat utime+stime misses; RSS stays on /proc). Throttling exposed on all three metric surfaces: cAdvisor-style container_cpu_cfs_throttled_{seconds,periods}_total on /metrics/resource and cocoon_vk_vm_cpu_throttled_{seconds,periods}_total on :9091.
  • Packaging: vk-cocoon.service sets CPUWeight=1000 (wins contention against co-located system.slice daemons); env example + docs pair VK_RESERVE_PERCENT with cocoon's cgroup_cpus fence and add COCOON_CGROUP_PARENT for non-default slices.

Notes

  • Scope path construction and cpu.stat parsing intentionally duplicate a small part of cocoon's cgroup package (vk-cocoon has no dependency edge to cocoon); hoisting the scope-naming contract into cocoon-common is a follow-up.
  • Behavior note: pods with CPU limits now get a real fractional quota (e.g. limits: 500m → half a core) instead of a rounded-up full core.

Verification

  • go test -race -count=1 ./... — all packages pass
  • make lint — 0 issues on GOOS=linux and GOOS=darwin
  • asl ./... — clean on both GOOS

CMGS added 5 commits August 5, 2026 18:45
Cocoon now caps every VM at Guaranteed-at-N via a per-VM cgroup scope,
so a rounded-up request would silently hard-cap burstable pods. Bound
vCPU and quota at the pod's CPU limit, derive weight from requests with
kubelet's cgroup v2 conversion, and pass the policy on every clone path
too — cocoon never inherits cgroup knobs from snapshots. Per-VM CPU and
throttling stats come from the scope's cpu.stat, which sees the
virtio/io_uring workers /proc utime+stime misses. vk-cocoon.service
raises CPUWeight within system.slice and packaging documents pairing
VK_RESERVE_PERCENT with cocoon's cgroup_cpus fence.
…rity

A 1m-9m CPU limit produced quota below cocoon's MinQuotaUs and every
run/clone was rejected; clamp to 1000us like kubelet. A pod with no CPU
resources left weight unset, falling to cocoon's vCPU-count default
instead of kubelet's BestEffort minimum share; always derive weight.
…, cgroup layout into vm/

Comment budget: provider.go's handleVMGone bullets restated the switch,
two recheck docs restated their callers, evictPod trimmed. Simplify:
podCPUPolicy's hand-rolled fallback uses selectQuantity; the redundant
min() guard in runDeferredRecheck matches the package's other backoff
loops; the twin patch-retry loops share patchWithRetry; the stats path
reads pod fields instead of re-splitting the map key; reconcileStaleCreates
uses the package fanOut idiom; the SAC guard has one definition. Altitude:
cgroup scope path + cpu.stat parsing move into vm/ beside COWSize and
ConsoleSocketPath — vm/ stays the single owner of cocoon's host layout.
@CMGS
CMGS merged commit a102494 into main Aug 5, 2026
4 checks passed
@CMGS
CMGS deleted the cpu-cgroup-qos branch August 5, 2026 12:21
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.

1 participant