mirror of
https://github.com/aljazceru/kata-containers.git
synced 2026-01-26 17:54:24 +01:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user