gpu: Add config to TOML

Update cold-plug and hot-plug setting to include bridge, root and
switch-port

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
This commit is contained in:
Zvonko Kaiser
2023-05-08 08:04:43 +00:00
parent da42801c38
commit 55a66eb7fb
20 changed files with 199 additions and 183 deletions

View File

@@ -47,7 +47,7 @@ func deviceLogger() *logrus.Entry {
return api.DeviceLogger()
}
// IsPCIeDevice Identify PCIe device by reading the size of the PCI config space
// IsPCIeDevice Identifies PCIe device by reading the size of the PCI config space
// Plain PCI device have 256 bytes of config space where PCIe devices have 4K
func IsPCIeDevice(bdf string) bool {
if len(strings.Split(bdf, ":")) == 2 {
@@ -157,9 +157,7 @@ func checkIgnorePCIClass(pciClass string, deviceBDF string, bitmask uint64) (boo
// GetAllVFIODevicesFromIOMMUGroup returns all the VFIO devices in the IOMMU group
// We can reuse this function at various levels, sandbox, container.
// Only the VFIO module is allowed to do bus assignments, all other modules need to
// ignore it if used as helper function to get VFIO information.
func GetAllVFIODevicesFromIOMMUGroup(device config.DeviceInfo, ignoreBusAssignment bool) ([]*config.VFIODev, error) {
func GetAllVFIODevicesFromIOMMUGroup(device config.DeviceInfo) ([]*config.VFIODev, error) {
vfioDevs := []*config.VFIODev{}
@@ -207,8 +205,8 @@ func GetAllVFIODevicesFromIOMMUGroup(device config.DeviceInfo, ignoreBusAssignme
Class: pciClass,
Rank: -1,
}
if isPCIe && !ignoreBusAssignment {
vfioPCI.Bus = fmt.Sprintf("%s%d", pcieRootPortPrefix, len(AllPCIeDevs))
if isPCIe {
vfioPCI.Rank = len(AllPCIeDevs)
AllPCIeDevs[deviceBDF] = true
}
vfio = vfioPCI

View File

@@ -73,7 +73,7 @@ func (device *VFIODevice) Attach(ctx context.Context, devReceiver api.DeviceRece
}
}()
device.VfioDevs, err = GetAllVFIODevicesFromIOMMUGroup(*device.DeviceInfo, false)
device.VfioDevs, err = GetAllVFIODevicesFromIOMMUGroup(*device.DeviceInfo)
if err != nil {
return err
}

View File

@@ -109,7 +109,7 @@ const defaultVMCacheEndpoint string = "/var/run/kata-containers/cache.sock"
// Default config file used by stateless systems.
var defaultRuntimeConfiguration = "@CONFIG_PATH@"
const defaultHotPlugVFIO = hv.BridgePort
const defaultHotPlugVFIO = hv.NoPort
const defaultColdPlugVFIO = hv.NoPort

View File

@@ -76,6 +76,7 @@ type factory struct {
VMCacheNumber uint `toml:"vm_cache_number"`
Template bool `toml:"enable_template"`
}
type hypervisor struct {
Path string `toml:"path"`
JailerPath string `toml:"jailer_path"`
@@ -886,6 +887,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
GuestMemoryDumpPath: h.GuestMemoryDumpPath,
GuestMemoryDumpPaging: h.GuestMemoryDumpPaging,
ConfidentialGuest: h.ConfidentialGuest,
SevSnpGuest: h.SevSnpGuest,
GuestSwap: h.GuestSwap,
Rootless: h.Rootless,
LegacySerial: h.LegacySerial,
@@ -1677,10 +1679,7 @@ func checkConfig(config oci.RuntimeConfig) error {
hotPlugVFIO := config.HypervisorConfig.HotPlugVFIO
coldPlugVFIO := config.HypervisorConfig.ColdPlugVFIO
machineType := config.HypervisorConfig.HypervisorMachineType
if err := checkPCIeConfig(coldPlugVFIO, machineType); err != nil {
return err
}
if err := checkPCIeConfig(hotPlugVFIO, machineType); err != nil {
if err := checkPCIeConfig(coldPlugVFIO, hotPlugVFIO, machineType); err != nil {
return err
}
@@ -1690,19 +1689,29 @@ func checkConfig(config oci.RuntimeConfig) error {
// checkPCIeConfig ensures the PCIe configuration is valid.
// Only allow one of the following settings for cold-plug:
// no-port, root-port, switch-port
func checkPCIeConfig(vfioPort hv.PCIePort, machineType string) error {
func checkPCIeConfig(coldPlug hv.PCIePort, hotPlug hv.PCIePort, machineType string) error {
// Currently only QEMU q35 supports advanced PCIe topologies
// firecracker, dragonball do not have right now any PCIe support
if machineType != "q35" {
return nil
}
if vfioPort == hv.NoPort || vfioPort == hv.BridgePort ||
vfioPort == hv.RootPort || vfioPort == hv.SwitchPort {
if coldPlug != hv.NoPort && hotPlug != hv.NoPort {
return fmt.Errorf("invalid hot-plug=%s and cold-plug=%s settings, only one of them can be set", coldPlug, hotPlug)
}
var port hv.PCIePort
if coldPlug != hv.NoPort {
port = coldPlug
}
if hotPlug != hv.NoPort {
port = hotPlug
}
if port == hv.NoPort || port == hv.BridgePort || port == hv.RootPort || port == hv.SwitchPort {
return nil
}
return fmt.Errorf("invalid vfio_port=%s setting, allowed values %s, %s, %s, %s",
vfioPort, hv.NoPort, hv.BridgePort, hv.RootPort, hv.SwitchPort)
coldPlug, hv.NoPort, hv.BridgePort, hv.RootPort, hv.SwitchPort)
}
// checkNetNsConfig performs sanity checks on disable_new_netns config.

View File

@@ -821,22 +821,22 @@ func TestRegexpContains(t *testing.T) {
//nolint: govet
type testData struct {
toMatch string
regexps []string
toMatch string
expected bool
}
data := []testData{
{regexps: []string{}, toMatch: "", expected: false},
{regexps: []string{}, toMatch: "nonempty", expected: false},
{regexps: []string{"simple"}, toMatch: "simple", expected: true},
{regexps: []string{"simple"}, toMatch: "some_simple_text", expected: true},
{regexps: []string{"simple"}, toMatch: "simp", expected: false},
{regexps: []string{"one", "two"}, toMatch: "one", expected: true},
{regexps: []string{"one", "two"}, toMatch: "two", expected: true},
{regexps: []string{"o*"}, toMatch: "oooo", expected: true},
{regexps: []string{"o*"}, toMatch: "oooa", expected: true},
{regexps: []string{"^o*$"}, toMatch: "oooa", expected: false},
{[]string{}, "", false},
{[]string{}, "nonempty", false},
{[]string{"simple"}, "simple", true},
{[]string{"simple"}, "some_simple_text", true},
{[]string{"simple"}, "simp", false},
{[]string{"one", "two"}, "one", true},
{[]string{"one", "two"}, "two", true},
{[]string{"o*"}, "oooo", true},
{[]string{"o*"}, "oooa", true},
{[]string{"^o*$"}, "oooa", false},
}
for _, d := range data {
@@ -850,25 +850,25 @@ func TestCheckPathIsInGlobs(t *testing.T) {
//nolint: govet
type testData struct {
toMatch string
globs []string
toMatch string
expected bool
}
data := []testData{
{globs: []string{}, toMatch: "", expected: false},
{globs: []string{}, toMatch: "nonempty", expected: false},
{globs: []string{"simple"}, toMatch: "simple", expected: false},
{globs: []string{"simple"}, toMatch: "some_simple_text", expected: false},
{globs: []string{"/bin/ls"}, toMatch: "/bin/ls", expected: true},
{globs: []string{"/bin/ls", "/bin/false"}, toMatch: "/bin/ls", expected: true},
{globs: []string{"/bin/ls", "/bin/false"}, toMatch: "/bin/false", expected: true},
{globs: []string{"/bin/ls", "/bin/false"}, toMatch: "/bin/bar", expected: false},
{globs: []string{"/bin/*ls*"}, toMatch: "/bin/ls", expected: true},
{globs: []string{"/bin/*ls*"}, toMatch: "/bin/false", expected: true},
{globs: []string{"bin/ls"}, toMatch: "/bin/ls", expected: false},
{globs: []string{"./bin/ls"}, toMatch: "/bin/ls", expected: false},
{globs: []string{"*/bin/ls"}, toMatch: "/bin/ls", expected: false},
{[]string{}, "", false},
{[]string{}, "nonempty", false},
{[]string{"simple"}, "simple", false},
{[]string{"simple"}, "some_simple_text", false},
{[]string{"/bin/ls"}, "/bin/ls", true},
{[]string{"/bin/ls", "/bin/false"}, "/bin/ls", true},
{[]string{"/bin/ls", "/bin/false"}, "/bin/false", true},
{[]string{"/bin/ls", "/bin/false"}, "/bin/bar", false},
{[]string{"/bin/*ls*"}, "/bin/ls", true},
{[]string{"/bin/*ls*"}, "/bin/false", true},
{[]string{"bin/ls"}, "/bin/ls", false},
{[]string{"./bin/ls"}, "/bin/ls", false},
{[]string{"*/bin/ls"}, "/bin/ls", false},
}
for _, d := range data {
@@ -923,10 +923,10 @@ func TestParseAnnotationUintConfiguration(t *testing.T) {
// nolint: govet
testCases := []struct {
err error
annotations map[string]string
validFunc func(uint64) error
expected uint64
err error
validFunc func(uint64) error
}{
{
annotations: map[string]string{key: ""},
@@ -1007,10 +1007,10 @@ func TestParseAnnotationBoolConfiguration(t *testing.T) {
// nolint: govet
testCases := []struct {
err error
annotationKey string
annotationValueList []string
expected bool
err error
}{
{
annotationKey: boolKey,
@@ -1207,8 +1207,8 @@ func TestNewMount(t *testing.T) {
assert := assert.New(t)
testCases := []struct {
in specs.Mount
out vc.Mount
in specs.Mount
}{
{
in: specs.Mount{