Skip to content

Commit 7f5233f

Browse files
committed
Report vendor VFIO profile availability per free VF
1 parent 495ab62 commit 7f5233f

2 files changed

Lines changed: 10 additions & 17 deletions

File tree

lib/devices/vendor_vfio_linux.go

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,13 @@ func (s vendorVFIOSysfs) discoverVFs() ([]VirtualFunction, error) {
8181
return vfs, nil
8282
}
8383

84-
// listProfiles aggregates creatable profiles per parent GPU. Free VFs on the
85-
// same GPU share its framebuffer, so counting each advertising VF overreports
86-
// availability. The driver only guarantees that a GPU still advertising a
87-
// type can fit one more instance of it, so report that per-GPU lower bound.
84+
// listProfiles counts each free VF advertising a type as one creatable
85+
// instance, matching the driver-reported units that mdev sums through
86+
// available_instances. This is a best-effort snapshot because creating on one
87+
// VF may revoke the type from siblings that share its GPU framebuffer.
8888
func (s vendorVFIOSysfs) listProfiles(vfs []VirtualFunction) ([]GPUProfile, error) {
8989
profilesByType := make(map[string]profileMetadata)
90-
creatableGPUs := make(map[string]map[string]struct{})
90+
creatableVFs := make(map[string]int)
9191
for _, vf := range vfs {
9292
creatable, err := s.readCreatableProfiles(vf.PCIAddress)
9393
if err != nil {
@@ -96,14 +96,7 @@ func (s vendorVFIOSysfs) listProfiles(vfs []VirtualFunction) ([]GPUProfile, erro
9696
for _, profile := range creatable {
9797
profilesByType[profile.TypeName] = profile
9898
if !vf.Allocated {
99-
gpu := vf.ParentGPU
100-
if gpu == "" {
101-
gpu = vf.PCIAddress
102-
}
103-
if creatableGPUs[profile.TypeName] == nil {
104-
creatableGPUs[profile.TypeName] = make(map[string]struct{})
105-
}
106-
creatableGPUs[profile.TypeName][gpu] = struct{}{}
99+
creatableVFs[profile.TypeName]++
107100
}
108101
}
109102
}
@@ -119,7 +112,7 @@ func (s vendorVFIOSysfs) listProfiles(vfs []VirtualFunction) ([]GPUProfile, erro
119112
profiles = append(profiles, GPUProfile{
120113
Name: profile.Name,
121114
FramebufferMB: profile.FramebufferMB,
122-
Available: len(creatableGPUs[profile.TypeName]),
115+
Available: creatableVFs[profile.TypeName],
123116
})
124117
}
125118
return profiles, nil

lib/devices/vendor_vfio_linux_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func TestVendorVFIODestroyRetainsAssignmentWhenOneVFIOPathIsMissing(t *testing.T
184184
}
185185
}
186186

187-
func TestVendorVFIOListProfilesCountsPerGPUNotPerVF(t *testing.T) {
187+
func TestVendorVFIOListProfilesCountsFreeVFs(t *testing.T) {
188188
t.Parallel()
189189

190190
sysfs := newTestVendorVFIOSysfs(t)
@@ -196,8 +196,8 @@ func TestVendorVFIOListProfilesCountsPerGPUNotPerVF(t *testing.T) {
196196
require.NoError(t, err)
197197
profiles, err := sysfs.listProfiles(vfs)
198198
require.NoError(t, err)
199-
assert.Equal(t, 2, profileAvailability(profiles, "NVIDIA L40S-48Q"),
200-
"free VFs share their parent GPU's capacity, so availability is per GPU")
199+
assert.Equal(t, 3, profileAvailability(profiles, "NVIDIA L40S-48Q"),
200+
"each free VF advertising the type counts as one creatable instance")
201201
}
202202

203203
func TestVendorVFIOCreateReportsCapacityWhenAllGPUsFull(t *testing.T) {

0 commit comments

Comments
 (0)