Skip to content

Commit

Permalink
Add acpiIndex selector (#488)
Browse files Browse the repository at this point in the history
acpiIndex selector selects devices based on their ACPI index if available.
This is useful e.g in VM environment where a device's ACPI index can be predefined
during VM creation time, device selection can then be based on that index.
  • Loading branch information
ian-howell authored Oct 5, 2023
1 parent 2cc723d commit 81a0e6a
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 48 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ These selectors are applicable when "deviceType" is "accelerator".
| "devices" | N | Target Devices' device Hex code as string | `string` list Default: `null` | "devices": ["154c", "1889", "1018"] |
| "drivers" | N | Target device driver names as string | `string` list Default: `null` | "drivers": ["vfio-pci"] |
| "pciAddresses" | N | Target device's pci address as string | `string` list Default: `null` | "pciAddresses": ["0000:03:02.0"] |
| "acpiIndexes" | N | Target device's acpi index as string | `string` list Default: `null` | "acpiIndexes": ["101"] |


#### Network devices selectors
Expand All @@ -321,6 +322,7 @@ These selectors are applicable when "deviceType" is "netDevice" (note: this is d
| "devices" | N | Target Devices' device Hex code as string | `string` list Default: `null` | "devices": ["154c", "1889", "1018"] |
| "drivers" | N | Target device driver names as string | `string` list Default: `null` | "drivers": ["vfio-pci"] |
| "pciAddresses" | N | Target device's pci address as string | `string` list Default: `null` | "pciAddresses": ["0000:03:02.0"] |
| "acpiIndexes" | N | Target device's acpi index as string | `string` list Default: `null` | "acpiIndexes": ["101"] |
| "pfNames" | N | functions from PF matches list of PF names | `string` list Default: `null` | "pfNames": ["enp2s2f0"] (See follow-up sections for some advance usage of "pfNames") |
| "rootDevices" | N | functions from PF matches list of PF PCI addresses | `string` list Default: `null` | "rootDevices": ["0000:86:00.0"] (See follow-up sections for some advance usage of "rootDevices") |
| "linkTypes" | N | The link type of the net device associated with the PCI device | `string` list Default: `null` | "linkTypes": ["ether"] |
Expand Down Expand Up @@ -441,10 +443,11 @@ The device plugin will initially discover all PCI network resources in the host
2. "devices" - The device hex code of device
3. "drivers" - The driver name the device is registered with
4. "pciAddresses" - The pci address of the device in BDF notation (if device type is accelerator or netDevice)
5. "auxTypes" - The type of auxiliary network device (if device type is auxNetDevice).
6. "pfNames" - The Physical function name
7. "rootDevices" - The Physical function PCI address
8. "linkTypes" - The link type of the net device associated with the PCI device
5. "acpiIndexes" - The acpi index of the device
6. "auxTypes" - The type of auxiliary network device (if device type is auxNetDevice).
7. "pfNames" - The Physical function name
8. "rootDevices" - The Physical function PCI address
9. "linkTypes" - The link type of the net device associated with the PCI device

If a single device matches multiple selector objects, it will only be allocated to the first one.

Expand Down
18 changes: 16 additions & 2 deletions pkg/devices/gen_pci.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,37 @@ package devices

import (
"github.com/jaypipes/ghw"

"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/utils"
)

// GenPciDevice implementation
type GenPciDevice struct {
pciAddr string
pciAddr string
acpiIndex string
}

// NewGenPciDevice returns GenPciDevice instance
func NewGenPciDevice(dev *ghw.PCIDevice) (*GenPciDevice, error) {
pciAddr := dev.Address

acpiIndex, err := utils.GetAcpiIndex(dev.Address)
if err != nil {
return nil, err
}

return &GenPciDevice{
pciAddr: pciAddr,
pciAddr: pciAddr,
acpiIndex: acpiIndex,
}, nil
}

// GetPciAddr returns pci address of the device
func (pd *GenPciDevice) GetPciAddr() string {
return pd.pciAddr
}

// GetAcpiIndex returns ACPI index of the device
func (pd *GenPciDevice) GetAcpiIndex() string {
return pd.acpiIndex
}
11 changes: 11 additions & 0 deletions pkg/factory/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ func (rf *resourceFactory) GetSelector(attr string, values []string) (types.Devi
return resources.NewRootDeviceSelector(values), nil
case "linkTypes":
return resources.NewLinkTypeSelector(values), nil
case "acpiIndexes":
return resources.NewAcpiIndexSelector(values), nil
case "ddpProfiles":
return resources.NewDdpSelector(values), nil
case "auxTypes":
Expand All @@ -102,6 +104,15 @@ func (rf *resourceFactory) GetSelector(attr string, values []string) (types.Devi
}
}

func (rf *resourceFactory) FilterBySelector(selectorName string, values []string, devicesToFilter []types.HostDevice) []types.HostDevice {
if len(values) > 0 {
if selector, err := rf.GetSelector(selectorName, values); err == nil {
return selector.Filter(devicesToFilter)
}
}
return devicesToFilter
}

// GetResourcePool returns an instance of resourcePool
func (rf *resourceFactory) GetResourcePool(rc *types.ResourceConfig, filteredDevice []types.HostDevice) (types.ResourcePool, error) {
devicePool := make(map[string]types.HostDevice)
Expand Down
56 changes: 14 additions & 42 deletions pkg/netdevice/netDeviceProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,64 +94,36 @@ func (np *netDeviceProvider) GetFilteredDevices(devices []types.HostDevice,
}

rf := np.rFactory

// filter by vendor list
if nf.Vendors != nil && len(nf.Vendors) > 0 {
if selector, err := rf.GetSelector("vendors", nf.Vendors); err == nil {
filteredDevice = selector.Filter(filteredDevice)
}
}
filteredDevice = rf.FilterBySelector("vendors", nf.Vendors, filteredDevice)

// filter by device list
if nf.Devices != nil && len(nf.Devices) > 0 {
if selector, err := rf.GetSelector("devices", nf.Devices); err == nil {
filteredDevice = selector.Filter(filteredDevice)
}
}
filteredDevice = rf.FilterBySelector("devices", nf.Devices, filteredDevice)

// filter by driver list
if nf.Drivers != nil && len(nf.Drivers) > 0 {
if selector, err := rf.GetSelector("drivers", nf.Drivers); err == nil {
filteredDevice = selector.Filter(filteredDevice)
}
}
filteredDevice = rf.FilterBySelector("drivers", nf.Drivers, filteredDevice)

// filter by pciAddresses list
if nf.PciAddresses != nil && len(nf.PciAddresses) > 0 {
if selector, err := rf.GetSelector("pciAddresses", nf.PciAddresses); err == nil {
filteredDevice = selector.Filter(filteredDevice)
}
}
filteredDevice = rf.FilterBySelector("pciAddresses", nf.PciAddresses, filteredDevice)

// filter by acpiIndexes list
filteredDevice = rf.FilterBySelector("acpiIndexes", nf.AcpiIndexes, filteredDevice)

// filter by PfNames list
if nf.PfNames != nil && len(nf.PfNames) > 0 {
if selector, err := rf.GetSelector("pfNames", nf.PfNames); err == nil {
filteredDevice = selector.Filter(filteredDevice)
}
}
filteredDevice = rf.FilterBySelector("pfNames", nf.PfNames, filteredDevice)

// filter by RootDevices list
if nf.RootDevices != nil && len(nf.RootDevices) > 0 {
if selector, err := rf.GetSelector("rootDevices", nf.RootDevices); err == nil {
filteredDevice = selector.Filter(filteredDevice)
}
}
filteredDevice = rf.FilterBySelector("rootDevices", nf.RootDevices, filteredDevice)

// filter by linkTypes list
if nf.LinkTypes != nil && len(nf.LinkTypes) > 0 {
if len(nf.LinkTypes) > 1 {
glog.Warningf("Link type selector should have a single value.")
}
if selector, err := rf.GetSelector("linkTypes", nf.LinkTypes); err == nil {
filteredDevice = selector.Filter(filteredDevice)
}
if len(nf.LinkTypes) > 1 {
glog.Warningf("Link type selector should have a single value.")
}
filteredDevice = rf.FilterBySelector("linkTypes", nf.LinkTypes, filteredDevice)

// filter by DDP Profiles list
if nf.DDPProfiles != nil && len(nf.DDPProfiles) > 0 {
if selector, err := rf.GetSelector("ddpProfiles", nf.DDPProfiles); err == nil {
filteredDevice = selector.Filter(filteredDevice)
}
}
filteredDevice = rf.FilterBySelector("ddpProfiles", nf.DDPProfiles, filteredDevice)

// filter for rdma devices
if nf.IsRdma {
Expand Down
20 changes: 20 additions & 0 deletions pkg/resources/deviceSelectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,26 @@ func (s *pciAddressSelector) Filter(inDevices []types.HostDevice) []types.HostDe
return filteredList
}

// NewAcpiIndexSelector returns a NetDevSelector interface for netDev list
func NewAcpiIndexSelector(acpiIndexes []string) types.DeviceSelector {
return &acpiIndexSelector{acpiIndexes: acpiIndexes}
}

type acpiIndexSelector struct {
acpiIndexes []string
}

func (s *acpiIndexSelector) Filter(inDevices []types.HostDevice) []types.HostDevice {
filteredList := make([]types.HostDevice, 0)
for _, dev := range inDevices {
acpiIndex := dev.(types.PciDevice).GetAcpiIndex()
if contains(s.acpiIndexes, acpiIndex) {
filteredList = append(filteredList, dev)
}
}
return filteredList
}

// NewPfNameSelector returns a NetDevSelector interface for netDev list
func NewPfNameSelector(pfNames []string) types.DeviceSelector {
return &pfNameSelector{pfNames: pfNames}
Expand Down
20 changes: 20 additions & 0 deletions pkg/resources/deviceSelectors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,24 @@ var _ = Describe("DeviceSelectors", func() {
})
})
})

Describe("acpiIndex selector", func() {
Context("filtering", func() {
It("should return devices matching the correct acpi index", func() {
acpiIndexes := []string{"101"}
sel := resources.NewAcpiIndexSelector(acpiIndexes)

dev0 := mocks.PciNetDevice{}
dev0.On("GetAcpiIndex").Return("101")
dev1 := mocks.PciNetDevice{}
dev1.On("GetAcpiIndex").Return("102")

in := []types.HostDevice{&dev0, &dev1}
filtered := sel.Filter(in)

Expect(filtered).To(ContainElement(&dev0))
Expect(filtered).NotTo(ContainElement(&dev1))
})
})
})
})
14 changes: 14 additions & 0 deletions pkg/types/mocks/AccelDevice.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions pkg/types/mocks/AuxNetDevice.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions pkg/types/mocks/HostDevice.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions pkg/types/mocks/NetDevice.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions pkg/types/mocks/PciDevice.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions pkg/types/mocks/PciNetDevice.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions pkg/types/mocks/ResourceFactory.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 81a0e6a

Please sign in to comment.