Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
927ab36
Place vGPU profiles the driver hides from creatable lists
yummybomb Oct 14, 2026
d4d32ba
Reset dirty VFs and classify driver rejections in hidden vGPU placement
yummybomb Oct 14, 2026
67ccc4e
Configure every vendor VFIO claim under the allocation lock
yummybomb Oct 14, 2026
0b19dba
Report vGPU driver rejections and drop rejected GPUs from not-creatab…
yummybomb Oct 14, 2026
3ad4efa
Test that a hidden vGPU profile is only offered on a clean VF
yummybomb Oct 14, 2026
95995a3
Reset dirty VFs before failing a claim whose hidden candidates were r…
yummybomb Oct 16, 2026
0c3eaa9
Describe the vGPU driver rejection counter as counting skipped GPUs
yummybomb Oct 16, 2026
6245232
Test that a claim counts a driver rejection for the skipped GPU
yummybomb Oct 16, 2026
b43bbd0
Test that a driver rejection does not reset a claimed sibling VF
yummybomb Oct 16, 2026
9bd194d
Drop restating and change-narrating vGPU comments
yummybomb Oct 16, 2026
12a59e3
Remove vGPU driver rejection tests other tests already cover
yummybomb Oct 16, 2026
2c9c09c
Keep the test for a hidden profile refused on every GPU
yummybomb Oct 16, 2026
188521d
Pack mixed-size vGPU placements to keep room for larger profiles
yummybomb Oct 14, 2026
fbe5948
Log when equal-size mode disables vGPU placement packing
yummybomb Oct 16, 2026
9580005
Test that a clean sibling VF does not block packing
yummybomb Oct 16, 2026
91af238
Test that vGPUs on another GPU do not block packing
yummybomb Oct 16, 2026
ccb0282
Test that a failed vGPU placement load is cached
yummybomb Oct 16, 2026
8a3fbc7
Drop redundant defensive code from vGPU placement packing
yummybomb Oct 16, 2026
f87d76f
Keep sorting placement IDs before choosing one
yummybomb Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/devices/GPU.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ On an mdev host, the response also includes the assigned mdev UUID:

### Ephemeral vGPU Lifecycle

vGPU assignments are created on instance start and released on stop or delete. Hypeman creates/removes an mdev on mdev hosts. On vendor VFIO hosts, it first reserves a VF by persisting its path in instance metadata, then writes the profile ID to `current_vgpu_type`. Metadata is the authoritative VF claim.
vGPU assignments are created on instance start and released on stop or delete. Hypeman creates/removes an mdev on mdev hosts. On vendor VFIO hosts, it selects a VF and writes the profile ID to `current_vgpu_type` under the allocation lock, so the driver confirms a placement remains before any later claim can take it, then reserves the VF by persisting its path in instance metadata. Metadata is the authoritative VF claim; a configured VF without one is dirty and is reset by the allocator.

```
Instance Create → Persist VF claim → Configure profile → Attach VF to VM → Instance Running
Instance Create → Configure profile → Persist VF claim → Attach VF to VM → Instance Running
Instance Stop/Delete → Reset profile → Remove VF claim → VF available again
```

Expand All @@ -106,6 +106,10 @@ before the hypervisor is signalled.

Hypeman reconciles metadata claims once at startup and every minute afterward, skipping hosts without GPUs. A claim whose VMM is confirmed dead is reset before the claim is removed. An ambiguous hypervisor ownership check preserves the claim, logs a warning, and increments `hypeman_instances_vgpu_liveness_uncertain_total`; the create and start cleanup paths preserve and count the same way. mdev hosts also sweep orphaned device-level assignments. Vendor VFIO hosts repair an unclaimed dirty VF when the allocator next selects it; repair checks for open VFIO handles before resetting `current_vgpu_type`. The allocator prefers VFs that are already clean, and a dirty VF that refuses its reset is skipped in favor of another candidate.

In mixed-size (heterogeneous) mode, `creatable_vgpu_types` under-reports. The driver drops a profile from every VF's list once its GPU holds as many vGPUs as that profile's equal-size instance limit (12 for L40S-4Q), even while a placement for it remains, and still accepts a `current_vgpu_type` write for it. The allocator remembers every profile each GPU has advertised, and a clean VF on a GPU that supports the requested profile but no longer advertises it stays a candidate, ranked after every GPU with a free VF that advertises it. If the driver rejects the claim's write, unclaimed dirty VFs on that GPU are reset and the write is retried once before the next GPU is tried, and `hypeman_instances_vgpu_driver_rejections_total` is incremented with the GPU's address; any other configure error fails the claim. If no candidate VF is left, unclaimed dirty VFs on the GPUs not yet tried are reset once and selection runs again. A free VF that advertises nothing is skipped (on L40S its GPU has no placement left for any size), as is one whose list cannot be read. This assumes every GPU is in mixed-size mode (`nvidia-smi vgpu -i <GPU> -shm 1`): in equal-size mode a GPU running a smaller profile hides larger ones for good, so each request for one costs a refused write on that GPU.

In mixed-size mode each vGPU also occupies a fixed run of placement slots, and the driver puts a new vGPU at the lowest free placement for its type. On an L40S that scatters 2Q across the runs 4Q needs: half of the 16 2Q placements overlap a 4Q placement. After writing `current_vgpu_type`, and before any VM attaches, hypeman moves the vGPU by writing `placement_id` to the free placement that blocks the fewest free placements of larger profiles, comparing the smallest larger size first. A tie keeps the driver's placement. On an L40S the first eight 2Q then land on the placements no 4Q overlaps, so a card holds eight 2Q and eight 4Q instead of eight 2Q and four 4Q. The placement table and mode come from `nvidia-smi vgpu -s -v -i <GPU>` and `nvidia-smi -q -i <GPU>`, cached per GPU for 10 minutes. Packing is skipped in equal-size mode, and any failure (no `nvidia-smi`, an unreadable sibling, a refused write) keeps the driver's placement.

### Hypervisor Support

Hypervisor selection for vGPU instances is caller policy; hypeman does not enforce it. In practice **QEMU is the only hypervisor with working vGPU support**:
Expand Down
5 changes: 5 additions & 0 deletions lib/devices/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,9 @@ var (

// ErrVGPUNotSupportedOnMacOS is returned for vGPU operations on macOS
ErrVGPUNotSupportedOnMacOS = errors.New("vGPU (mdev) is not supported on macOS")

// ErrVGPUTypeRejected is returned when the driver refuses a vendor VFIO
// current_vgpu_type write, which is how it reports that the VF's GPU has
// no placement left for the type
ErrVGPUTypeRejected = errors.New("driver rejected vGPU type")
)
Loading
Loading