Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 12 additions & 5 deletions lib/devices/vendor_vfio_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,21 +331,28 @@ func (s vendorVFIOSysfs) vfioDeviceInUse(vfAddress string) (bool, error) {
return false, nil
}

// parseCreatableVGPUTypes reads the driver's creatable_vgpu_types listing:
//
// ID : vGPU Name
// 1147 : NVIDIA L40S-1Q
func parseCreatableVGPUTypes(value string) ([]profileMetadata, error) {
profiles := make([]profileMetadata, 0)
for lineNumber, line := range strings.Split(value, "\n") {
fields := strings.Fields(line)
if len(fields) == 0 {
if strings.TrimSpace(line) == "" {
continue
}
if len(fields) < 2 {
typeID, name, found := strings.Cut(line, ":")
typeID = strings.TrimSpace(typeID)
name = strings.TrimSpace(name)
if !found || name == "" {
return nil, fmt.Errorf("parse creatable vGPU types line %d: %q", lineNumber+1, line)
}
typeID := fields[len(fields)-1]
if typeID == "ID" {
continue
}
if _, err := strconv.Atoi(typeID); err != nil {
return nil, fmt.Errorf("parse vGPU type ID %q: %w", typeID, err)
}
name := strings.Join(fields[:len(fields)-1], " ")
profiles = append(profiles, profileMetadata{
TypeName: typeID,
Name: name,
Expand Down
21 changes: 17 additions & 4 deletions lib/devices/vendor_vfio_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (
"github.com/stretchr/testify/require"
)

const testCreatableTypes = `NVIDIA L40S-1Q 1147
NVIDIA L40S-2Q 1148
NVIDIA L40S-48Q 1159
const testCreatableTypes = `ID : vGPU Name
1147 : NVIDIA L40S-1Q
1148 : NVIDIA L40S-2Q
1159 : NVIDIA L40S-48Q
`

func TestParseCreatableVGPUTypes(t *testing.T) {
Expand Down Expand Up @@ -101,10 +102,22 @@ func TestVendorVFIOReconcilePreservesLegacyGroupFD(t *testing.T) {
assertFileValue(t, filepath.Join(sysfs.pciDevicesPath, "0000:e3:00.4", "nvidia", "current_vgpu_type"), "1148")
}

// A GPU with no framebuffer left prints the header and nothing else.
func TestParseCreatableVGPUTypesHeaderOnly(t *testing.T) {
t.Parallel()

profiles, err := parseCreatableVGPUTypes("ID : vGPU Name\n")
require.NoError(t, err)
assert.Empty(t, profiles)
}

func TestParseCreatableVGPUTypesRejectsMalformedLine(t *testing.T) {
t.Parallel()

_, err := parseCreatableVGPUTypes("NVIDIA L40S-1Q not-an-id")
_, err := parseCreatableVGPUTypes("NVIDIA L40S-1Q 1147")
require.Error(t, err)

_, err = parseCreatableVGPUTypes("not-an-id : NVIDIA L40S-1Q")
require.Error(t, err)
}

Expand Down
Loading