diff --git a/cmd/api/api/instances.go b/cmd/api/api/instances.go index 89c927a6..9b259035 100644 --- a/cmd/api/api/instances.go +++ b/cmd/api/api/instances.go @@ -349,10 +349,10 @@ func (s *ApiService) CreateInstance(ctx context.Context, request oapi.CreateInst // errors.Is case would match the cause and hide the pending vGPU cleanup. case errors.As(err, &vgpuPending): log.ErrorContext(ctx, "failed to create instance", "error", err, "image", request.Body.Image) - message := fmt.Sprintf("failed to create instance; vGPU release failed during rollback and instance %s retains the assignment, delete it to retry", vgpuPending.InstanceID) + message := fmt.Sprintf("failed to create instance: %v; vGPU release failed during rollback and instance %s retains the assignment, delete it to retry", vgpuPending.Err, vgpuPending.InstanceID) innerCode := "vgpu_retained_instance" if !vgpuPending.Retained { - message = fmt.Sprintf("failed to create instance; vGPU release failed during rollback and the retention record for instance %s could not be saved; the assignment is recovered on the next startup reconcile", vgpuPending.InstanceID) + message = fmt.Sprintf("failed to create instance: %v; vGPU release failed during rollback and the retention record for instance %s could not be saved; the assignment is recovered on the next startup reconcile", vgpuPending.Err, vgpuPending.InstanceID) innerCode = "vgpu_unretained_instance" } return oapi.CreateInstance500JSONResponse{ diff --git a/cmd/api/api/instances_test.go b/cmd/api/api/instances_test.go index 848661ed..c4138cf6 100644 --- a/cmd/api/api/instances_test.go +++ b/cmd/api/api/instances_test.go @@ -76,6 +76,8 @@ func TestCreateInstance_VGPUCleanupPendingBeatsWrappedErrorMapping(t *testing.T) require.True(t, ok, "expected 500 vgpu_cleanup_pending, got %T", resp) assert.EqualValues(t, "vgpu_cleanup_pending", pending.Code) assert.Contains(t, pending.Message, "inst-1") + assert.Contains(t, pending.Message, network.ErrNameExists.Error(), + "the underlying create failure must survive the cleanup guidance") assert.Contains(t, pending.Message, "delete it to retry") require.NotNil(t, pending.InnerError) require.NotNil(t, pending.InnerError.Code) @@ -101,6 +103,8 @@ func TestCreateInstance_VGPUCleanupPendingWithoutRetentionUsesReconcileGuidance( require.True(t, ok, "expected 500 vgpu_cleanup_pending, got %T", resp) assert.EqualValues(t, "vgpu_cleanup_pending", pending.Code) assert.Contains(t, pending.Message, "retention record for instance inst-1 could not be saved") + assert.Contains(t, pending.Message, network.ErrNameExists.Error(), + "the underlying create failure must survive the cleanup guidance") assert.Contains(t, pending.Message, "startup reconcile") assert.NotContains(t, pending.Message, "delete") require.NotNil(t, pending.InnerError) diff --git a/lib/devices/vendor_vfio_linux.go b/lib/devices/vendor_vfio_linux.go index ceab85ec..d67ddbc0 100644 --- a/lib/devices/vendor_vfio_linux.go +++ b/lib/devices/vendor_vfio_linux.go @@ -81,22 +81,37 @@ func (s vendorVFIOSysfs) discoverVFs() ([]VirtualFunction, error) { return vfs, nil } -// listProfiles counts each free VF advertising a type as one creatable -// instance, matching the driver-reported units that mdev sums through -// available_instances. This is a best-effort snapshot because creating on one -// VF may revoke the type from siblings that share its GPU framebuffer. +// listProfiles reports a conservative estimate of how many instances of each +// profile are concurrently creatable. Free VFs on the same GPU share its +// framebuffer, so counting every advertising VF overreports capacity: one 48Q +// assignment can revoke the type from all sibling VFs. Each GPU instead +// contributes min(free VFs advertising the type, remaining framebuffer / +// profile framebuffer), where the largest profile still creatable on the GPU +// is a lower bound on its remaining framebuffer. func (s vendorVFIOSysfs) listProfiles(vfs []VirtualFunction) ([]GPUProfile, error) { profilesByType := make(map[string]profileMetadata) - creatableVFs := make(map[string]int) + freeVFsByGPU := make(map[string]map[string]int) + remainingFBByGPU := make(map[string]int) for _, vf := range vfs { creatable, err := s.readCreatableProfiles(vf.PCIAddress) if err != nil { return nil, err } + gpu := vf.ParentGPU + if gpu == "" { + gpu = vf.PCIAddress + } for _, profile := range creatable { profilesByType[profile.TypeName] = profile - if !vf.Allocated { - creatableVFs[profile.TypeName]++ + if vf.Allocated { + continue + } + if freeVFsByGPU[gpu] == nil { + freeVFsByGPU[gpu] = make(map[string]int) + } + freeVFsByGPU[gpu][profile.TypeName]++ + if profile.FramebufferMB > remainingFBByGPU[gpu] { + remainingFBByGPU[gpu] = profile.FramebufferMB } } } @@ -109,15 +124,35 @@ func (s vendorVFIOSysfs) listProfiles(vfs []VirtualFunction) ([]GPUProfile, erro profiles := make([]GPUProfile, 0, len(metadata)) for _, profile := range metadata { + available := 0 + for gpu, freeVFs := range freeVFsByGPU { + available += gpuProfileCapacity(freeVFs[profile.TypeName], remainingFBByGPU[gpu], profile.FramebufferMB) + } profiles = append(profiles, GPUProfile{ Name: profile.Name, FramebufferMB: profile.FramebufferMB, - Available: creatableVFs[profile.TypeName], + Available: available, }) } return profiles, nil } +// gpuProfileCapacity estimates how many instances of a profile one GPU can +// still create concurrently. When a profile's framebuffer is unknown (0), the +// free VF count is the only signal available. +func gpuProfileCapacity(freeVFs, remainingFB, profileFB int) int { + if freeVFs == 0 { + return 0 + } + if profileFB <= 0 || remainingFB <= 0 { + return freeVFs + } + if byFB := remainingFB / profileFB; byFB < freeVFs { + return byFB + } + return freeVFs +} + func (s vendorVFIOSysfs) create(ctx context.Context, profileName, instanceID string) (*VGPUDevice, error) { vendorVFIOMu.Lock() defer vendorVFIOMu.Unlock() diff --git a/lib/devices/vendor_vfio_linux_test.go b/lib/devices/vendor_vfio_linux_test.go index 4555f5c2..b68a9f91 100644 --- a/lib/devices/vendor_vfio_linux_test.go +++ b/lib/devices/vendor_vfio_linux_test.go @@ -184,7 +184,7 @@ func TestVendorVFIODestroyRetainsAssignmentWhenOneVFIOPathIsMissing(t *testing.T } } -func TestVendorVFIOListProfilesCountsFreeVFs(t *testing.T) { +func TestVendorVFIOListProfilesReportsPerGPUCapacity(t *testing.T) { t.Parallel() sysfs := newTestVendorVFIOSysfs(t) @@ -196,8 +196,30 @@ func TestVendorVFIOListProfilesCountsFreeVFs(t *testing.T) { require.NoError(t, err) profiles, err := sysfs.listProfiles(vfs) require.NoError(t, err) - assert.Equal(t, 3, profileAvailability(profiles, "NVIDIA L40S-48Q"), - "each free VF advertising the type counts as one creatable instance") + assert.Equal(t, 2, profileAvailability(profiles, "NVIDIA L40S-48Q"), + "one 48Q consumes a whole GPU, so two GPUs mean two creatable instances despite three free VFs") + assert.Equal(t, 3, profileAvailability(profiles, "NVIDIA L40S-2Q"), + "small profiles stay capped by the free VF count") +} + +func TestVendorVFIOListProfilesCapsCapacityByRemainingFramebuffer(t *testing.T) { + t.Parallel() + + // One 48G GPU with a 24Q already assigned: siblings only advertise up to + // 24Q, so at most one more 24Q fits despite two free VFs. + remaining := "ID : vGPU Name\n1147 : NVIDIA L40S-1Q\n1153 : NVIDIA L40S-24Q\n" + sysfs := newTestVendorVFIOSysfs(t) + sysfs.addVF(t, "0000:82:00.0", "0000:82:00.4", "42", "1153", remaining) + sysfs.addVF(t, "0000:82:00.0", "0000:82:00.5", "43", "0", remaining) + sysfs.addVF(t, "0000:82:00.0", "0000:82:00.6", "44", "0", remaining) + + vfs, err := sysfs.discoverVFs() + require.NoError(t, err) + profiles, err := sysfs.listProfiles(vfs) + require.NoError(t, err) + assert.Equal(t, 1, profileAvailability(profiles, "NVIDIA L40S-24Q")) + assert.Equal(t, 2, profileAvailability(profiles, "NVIDIA L40S-1Q"), + "framebuffer allows more 1Q instances than free VFs, so the VF count caps it") } func TestVendorVFIOCreateReportsCapacityWhenAllGPUsFull(t *testing.T) { diff --git a/lib/oapi/oapi.go b/lib/oapi/oapi.go index 44930346..bd0f0453 100644 --- a/lib/oapi/oapi.go +++ b/lib/oapi/oapi.go @@ -833,7 +833,7 @@ type GPUConfig struct { // GPUProfile Available vGPU profile type GPUProfile struct { - // Available Number of virtual functions currently able to create this profile. Best-effort: creating an instance may reduce availability on sibling functions sharing GPU framebuffer. + // Available Conservative estimate of instances concurrently creatable with this profile across all GPUs, bounded per GPU by free virtual functions and remaining framebuffer. Best-effort: recomputed from driver state on each query. Available int `json:"available"` // FramebufferMb Frame buffer size in MB @@ -17703,227 +17703,228 @@ var swaggerSpec = []string{ "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", + "fvm/AQAA//9dup1U9LgBAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/lib/resources/monitoring.go b/lib/resources/monitoring.go index dc6992a2..1aef5a2b 100644 --- a/lib/resources/monitoring.go +++ b/lib/resources/monitoring.go @@ -203,7 +203,7 @@ func newMonitoringMetrics(meter metric.Meter, mgr *Manager) error { gpuProfileSlots, err := meter.Int64ObservableGauge( "hypeman_resources_gpu_profile_slots", - metric.WithDescription("Virtual functions able to create each vGPU profile (best-effort snapshot)"), + metric.WithDescription("Estimated concurrently creatable instances per vGPU profile (best-effort snapshot)"), ) if err != nil { return err diff --git a/openapi.yaml b/openapi.yaml index 23ec8574..4e2e34f0 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1566,7 +1566,7 @@ components: example: 1024 available: type: integer - description: "Number of virtual functions currently able to create this profile. Best-effort: creating an instance may reduce availability on sibling functions sharing GPU framebuffer." + description: "Conservative estimate of instances concurrently creatable with this profile across all GPUs, bounded per GPU by free virtual functions and remaining framebuffer. Best-effort: recomputed from driver state on each query." example: 59 PassthroughDevice: