Skip to content

Quarantine unhealthy vGPU VFs via a persisted health store - #462

Open
yummybomb wants to merge 6 commits into
hypeship/vendor-vfio-vgpufrom
hypeship/vgpu-vf-quarantine
Open

Quarantine unhealthy vGPU VFs via a persisted health store#462
yummybomb wants to merge 6 commits into
hypeship/vendor-vfio-vgpufrom
hypeship/vgpu-vf-quarantine

Conversation

@yummybomb

@yummybomb yummybomb commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Bottom half of the wedged-VF work (detection lands separately on top, in #435). This PR adds the quarantine machinery: a persisted VF health store plus the placement, admission, and API changes that act on it. Nothing in this PR reports failures automatically yet — the store is fed by the guest-side detection in #435, and by operators editing the state file per the runbook.

  • VF init failures are tallied in <data-dir>/gpu/vf-health.json per instance assignment; a VF is quarantined once failures accumulate from gpu.vf_quarantine_threshold distinct assignments (default 2). An exact-assignment success report clears the match and older tallies, and rescinds that assignment's quarantine.
  • Quarantined VFs are excluded from placement and advertised profile availability. Cards with quarantined VFs are deprioritized, and selection among equivalent free VFs is randomized so one VF cannot capture every placement.
  • GET /resources reports allocatable_slots and quarantined_slots; GPU admission gates on the allocatable count.

Safety and failure handling

  • An unreadable or invalid state file fails closed: mutations are refused, placement and advertised availability are disabled, and loads are retried after repair.
  • State writes fsync the temp file before the rename and the directory after, so a host crash cannot silently drop a quarantine.
  • State write failures before rename roll back in memory. Failures after rename retain the visible state and keep placement closed until a later report durably re-persists it.
  • Quarantine only removes capacity — it never touches a running instance.

lib/devices/GPU.md documents the store semantics, draining the parent GPU, the SR-IOV recovery cycle, and clearing quarantine state.

Testing

Passed:

go test -race ./lib/devices ./lib/paths ./lib/resources ./cmd/api/config
go vet ./lib/devices ./lib/resources ./lib/paths ./cmd/api/config ./cmd/api/api

The full lib/instances suite was also attempted; TestCreateInstanceWithNetwork fails in this environment on both this branch and its base (it boots a real VM image), so it is environmental, not introduced here. The stacked detection PR's tree is byte-identical to the previously reviewed and tested head of #435.


Note

Medium Risk
Changes vGPU placement, admission, and persisted state with fail-closed behavior; misconfigured or corrupted vf-health.json can block new vGPU placements until repaired, but running VMs are not torn down.

Overview
Adds vGPU VF quarantine for wedged virtual functions: guest driver init failures are tallied in persisted vf-health.json under the data dir, and VFs are quarantined after failures from gpu.vf_quarantine_threshold distinct instance assignments (default 2, configurable and validated at startup).

Placement and capacity: Vendor-VFIO selection skips quarantined VFs, deprioritizes parent GPUs that have quarantined VFs, and randomizes among equivalent free VFs on the chosen card. Profile availability and VGPUAvailability exclude quarantined VFs. Corrupt or unwritable health state fails closed (no placement / no advertised allocatable capacity until load or persist succeeds).

API and admission: GET /resources GPU status adds allocatable_slots and quarantined_slots; GPU reservation/validation gates on allocatable slots and returns explicit errors when VF health is unavailable. ReportVFInitFailure / ReportVFInitSuccess APIs exist for future guest detection (#435) and manual operation; this PR does not wire automatic failure reporting.

Docs (GPU.md, config.example.yaml) cover store semantics, draining, and SR-IOV recovery. Extensive unit tests cover the health store and placement behavior.

Reviewed by Cursor Bugbot for commit 5a8fcae. Bugbot is set up for automated code reviews on this repo. Configure here.

@yummybomb
yummybomb marked this pull request as ready for review August 27, 2026 17:28
@yummybomb
yummybomb force-pushed the hypeship/vgpu-vf-quarantine branch from 182853a to 34d27c2 Compare August 27, 2026 17:29
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
-->

✱ stlc build

go code · compare

Your SDK build was successful.

generate ✅bootstrap ✅format ✅

116 files generated at 43ea324 (pushed)

go get github.com/kernel/hypeman-go-staging@43ea3242fbaa187fa8dcfe50b05a08ae53f8d364
python code · compare

Your SDK build was successful.

generate ✅bootstrap ✅format ✅

230 files generated at f9e149e (pushed)

typescript code · compare

Your SDK build was successful.

generate ✅bootstrap ✅format ✅

138 files generated at 8f55018 (pushed)

Diagnostics: ❗ 0 new / 1 total error, 💡 0 new / 5 total note
LevelCodeMessageTargets
Build metadata
Buildbd_76Dw5GKc-gilded-jam
Timestamp2026-08-28T17:32:01.974Z
stlc8413509
Spec hash3652069ab265
Config hash55e15f6f4434

This comment is auto-generated by stlc and is kept up to date as you push.
If you push new commits, re-run this workflow to update this comment.
Last updated: 2026-08-28 17:32:25 UTC

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2bea9f0. Configure here.

Comment thread lib/devices/vf_health.go Outdated
@yummybomb

Copy link
Copy Markdown
Contributor Author

Cleanup pass (deslop / test dedup), no behavior changes:

  • b4f924f4 — the identical lock-order comment appeared verbatim in both ReportVFInitFailure and ReportVFInitSuccess; it now lives once on the vendorVFIOMu declaration.
  • 94f8496e — collapsed redundant test cases in vf_health_test.go (595 → 559 lines, 22 → 19 tests):
    • TestVGPUAvailabilityExcludesOnlyQuarantinedVFs folded into TestVGPUAvailability (below-threshold tally asserted alongside the quarantined/allocated cases).
    • TestCheckedAddressesFailsClosedOnUnloadedState removed; its unique repaired-state recovery assertion moved into TestVGPUAvailabilityFailsWhenStoreUnavailable via the public API, and the invalid-record table already asserts checkedAddresses errors per case.
    • TestReportVFInitFailureRespectsConfiguredThreshold removed — subsumed by TestReportVFInitFailureQuarantinesAtThreshold (outcomes/counts/threshold field) and the two threshold re-evaluation tests.

The persist-failure/rollback/retry test family was left intact — each pins a distinct branch fixed by 2bea9f08/a69fae1b/ce05d4eb. Exported surface is untouched (ReportVFInit*, VFHealthStoreUnavailable, TotalQuarantinedVFs, result types), but the stacked #435 will need a rebase: its diff context overlaps the removed comments in vf_health.go, and it anchors new tests near TestReportVFInitSuccessWithoutMatchingFailureClearsNothing.

Verified: go vet + go test -race ./lib/devices ./lib/paths ./lib/resources ./cmd/api/config pass, and make oapi-generate reproduces lib/oapi/oapi.go byte-identical.

Add a VF health store persisted at <data-dir>/gpu/vf-health.json: init
failures reported against a VF are tallied per instance assignment, and
once failures accumulate from gpu.vf_quarantine_threshold distinct
assignments (default 2) the VF is quarantined. Quarantined VFs are
excluded from placement and advertised profile availability, cards with
quarantined VFs are deprioritized, and selection among equivalent free
VFs is randomized. An exact-assignment success report clears the match
and older tallies and rescinds that assignment's quarantine.

An unreadable or invalid state file fails closed: mutations are refused,
placement and advertised availability are disabled, and loads are
retried after repair. Writes fsync before and after the rename.

GET /resources reports allocatable_slots and quarantined_slots, and GPU
admission gates on the allocatable count. GPU.md documents the store
semantics, draining the parent GPU, the SR-IOV recovery cycle, and
clearing quarantine state.
A failed state write previously rolled memory back and left the store
reporting healthy, so a VF whose threshold-crossing failure could not be
persisted stayed allocatable. Latch write failures and refuse placement
until a later write succeeds; re-reported markers retry the write.

Also make acknowledged reports crash-durable (fsync the parent when the
state dir is first created, treat directory sync failures as persist
failures instead of logging success), and re-evaluate persisted tallies
against the configured threshold at load and on threshold changes so a
lowered gpu.vf_quarantine_threshold applies to existing failures.
Fold the below-threshold placement assertion into TestVGPUAvailability
and the repaired-state recovery assertion into
TestVGPUAvailabilityFailsWhenStoreUnavailable, exercising both through
the public API. Drop TestReportVFInitFailureRespectsConfiguredThreshold
and TestCheckedAddressesFailsClosedOnUnloadedState, whose remaining
coverage is subsumed by the threshold re-evaluation and invalid-record
tests.
@yummybomb
yummybomb force-pushed the hypeship/vgpu-vf-quarantine branch from 94f8496 to 5a8fcae Compare August 28, 2026 17:28
@yummybomb
yummybomb requested a review from sjmiller609 August 28, 2026 18:28
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