Skip to content

Commit 551f924

Browse files
authored
Merge pull request #32 from rollandf/rdma-discovery
feat: rdma discovery
2 parents 87c9c34 + c5cb888 commit 551f924

File tree

10 files changed

+432
-57
lines changed

10 files changed

+432
-57
lines changed

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/k8snetworkplumbingwg/dra-driver-sriov
33
go 1.25.3
44

55
require (
6+
github.com/Mellanox/rdmamap v1.1.0
67
github.com/containerd/nri v0.11.0
78
github.com/containernetworking/cni v1.3.0
89
github.com/jaypipes/ghw v0.21.2
@@ -77,6 +78,8 @@ require (
7778
github.com/sirupsen/logrus v1.9.3 // indirect
7879
github.com/spf13/cobra v1.9.1 // indirect
7980
github.com/tetratelabs/wazero v1.10.1 // indirect
81+
github.com/vishvananda/netlink v1.3.1 // indirect
82+
github.com/vishvananda/netns v0.0.5 // indirect
8083
github.com/x448/float16 v0.8.4 // indirect
8184
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
8285
github.com/yusufpapurcu/wmi v1.2.4 // indirect

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
22
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
3+
github.com/Mellanox/rdmamap v1.1.0 h1:A/W1wAXw+6vm58f3VklrIylgV+eDJlPVIMaIKuxgUT4=
4+
github.com/Mellanox/rdmamap v1.1.0/go.mod h1:fN+/V9lf10ABnDCwTaXRjeeWijLt2iVLETnK+sx/LY8=
35
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
46
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
57
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -178,6 +180,10 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
178180
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
179181
github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU=
180182
github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4=
183+
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
184+
github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
185+
github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
186+
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
181187
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
182188
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
183189
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
@@ -242,9 +248,12 @@ golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
242248
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
243249
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
244250
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
251+
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
245252
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
246253
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
247254
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
255+
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
256+
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
248257
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
249258
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
250259
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=

pkg/consts/consts.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const (
3838
AttributeVFID = DriverName + "/vfID"
3939
AttributeResourceName = DriverName + "/resourceName"
4040
AttributeLinkType = DriverName + "/linkType"
41+
AttributeRDMACapable = DriverName + "/rdmaCapable"
4142
// Use upstream Kubernetes standard attribute prefix for numaNode
4243
AttributeNumaNode = deviceattribute.StandardDeviceAttributePrefix + "numaNode"
4344
// Use upstream Kubernetes standard attribute prefix for pciAddress
@@ -54,6 +55,9 @@ const (
5455
LinkTypeEthernet = "ethernet"
5556
LinkTypeInfiniband = "infiniband"
5657
LinkTypeUnknown = "unknown"
58+
59+
// RDMA device constants
60+
SysClassInfiniband = "/sys/class/infiniband"
5761
)
5862

5963
// Kubernetes standard attributes

pkg/devicestate/discovery.go

Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,11 @@ func DiscoverSriovDevices() (types.AllocatableDevices, error) {
7777
eswitchMode := host.GetHelpers().GetNicSriovMode(device.Address)
7878

7979
// Get NUMA node information
80+
// -1 indicates NUMA is not supported/enabled (standard Linux convention)
8081
numaNode, err := host.GetHelpers().GetNumaNode(device.Address)
8182
if err != nil {
82-
logger.Error(err, "Failed to get NUMA node, using default", "address", device.Address)
83-
numaNode = "0" // Default to node 0 if we can't determine it
83+
logger.Error(err, "Failed to get NUMA node, using -1 (not supported)", "address", device.Address)
84+
numaNode = "-1"
8485
}
8586

8687
// Get PCIe Root Complex information using upstream Kubernetes implementation
@@ -142,69 +143,83 @@ func DiscoverSriovDevices() (types.AllocatableDevices, error) {
142143

143144
logger.Info("Found VFs for PF", "pf", pfInfo.NetName, "vfCount", len(vfList))
144145

146+
// Parse NUMA node value. Keep the actual value including -1 which indicates
147+
// NUMA is not supported/enabled (standard Linux convention).
148+
// This allows users to filter devices based on NUMA availability.
149+
numaNodeInt, err := strconv.ParseInt(pfInfo.NumaNode, 10, 64)
150+
if err != nil {
151+
logger.Error(err, "Failed to parse NUMA node, defaulting to -1",
152+
"pf", pfInfo.NetName, "numaNodeStr", pfInfo.NumaNode)
153+
numaNodeInt = -1
154+
}
155+
numaNodeIntPtr := ptr.To(numaNodeInt)
156+
145157
for _, vfInfo := range vfList {
146158
deviceName := strings.ReplaceAll(vfInfo.PciAddress, ":", "-")
147159
deviceName = strings.ReplaceAll(deviceName, ".", "-")
148160

161+
// Check RDMA capability for this VF
162+
rdmaCapable := host.GetHelpers().VerifyRDMACapability(vfInfo.PciAddress)
163+
149164
logger.V(2).Info("Adding VF device to resource list",
150165
"deviceName", deviceName,
151166
"vfAddress", vfInfo.PciAddress,
152167
"vfID", vfInfo.VFID,
153168
"vfDeviceID", vfInfo.DeviceID,
154169
"pfDeviceID", pfInfo.DeviceID,
155-
"pf", pfInfo.NetName)
170+
"pf", pfInfo.NetName,
171+
"rdmaCapable", rdmaCapable)
156172

157-
resourceList[deviceName] = resourceapi.Device{
158-
Name: deviceName,
159-
Attributes: map[resourceapi.QualifiedName]resourceapi.DeviceAttribute{
160-
consts.AttributeVendorID: {
161-
StringValue: ptr.To(pfInfo.VendorID),
162-
},
163-
consts.AttributeDeviceID: {
164-
StringValue: ptr.To(vfInfo.DeviceID),
165-
},
166-
consts.AttributePFDeviceID: {
167-
StringValue: ptr.To(pfInfo.DeviceID),
168-
},
169-
consts.AttributePciAddress: {
170-
StringValue: ptr.To(vfInfo.PciAddress),
171-
},
172-
consts.AttributePFName: {
173-
StringValue: ptr.To(pfInfo.NetName),
174-
},
175-
consts.AttributeEswitchMode: {
176-
StringValue: ptr.To(pfInfo.EswitchMode),
177-
},
178-
consts.AttributeVFID: {
179-
IntValue: ptr.To(int64(vfInfo.VFID)),
180-
},
181-
consts.AttributeNumaNode: {
182-
IntValue: func() *int64 {
183-
numaNodeInt, err := strconv.ParseInt(pfInfo.NumaNode, 10, 64)
184-
if err != nil {
185-
// Default to -1 if parsing fails
186-
return ptr.To(int64(-1))
187-
}
188-
return ptr.To(numaNodeInt)
189-
}(),
190-
},
191-
// PCIe Root Complex (upstream Kubernetes standard) - for topology-aware scheduling
192-
consts.AttributePCIeRoot: {
193-
StringValue: ptr.To(pfInfo.PCIeRoot),
194-
},
195-
// Immediate parent PCI address - for granular filtering
196-
consts.AttributeParentPciAddress: {
197-
StringValue: ptr.To(pfInfo.ParentPciAddress),
198-
},
199-
// Standard Kubernetes PCI address attribute
200-
consts.AttributeStandardPciAddress: {
201-
StringValue: ptr.To(vfInfo.PciAddress),
202-
},
203-
// Link type (ethernet, infiniband, etc.)
204-
consts.AttributeLinkType: {
205-
StringValue: ptr.To(pfInfo.LinkType),
206-
},
173+
// Build device attributes
174+
attributes := map[resourceapi.QualifiedName]resourceapi.DeviceAttribute{
175+
consts.AttributeVendorID: {
176+
StringValue: ptr.To(pfInfo.VendorID),
177+
},
178+
consts.AttributeDeviceID: {
179+
StringValue: ptr.To(vfInfo.DeviceID),
180+
},
181+
consts.AttributePFDeviceID: {
182+
StringValue: ptr.To(pfInfo.DeviceID),
183+
},
184+
consts.AttributePciAddress: {
185+
StringValue: ptr.To(vfInfo.PciAddress),
186+
},
187+
consts.AttributePFName: {
188+
StringValue: ptr.To(pfInfo.NetName),
189+
},
190+
consts.AttributeEswitchMode: {
191+
StringValue: ptr.To(pfInfo.EswitchMode),
207192
},
193+
consts.AttributeVFID: {
194+
IntValue: ptr.To(int64(vfInfo.VFID)),
195+
},
196+
consts.AttributeNumaNode: {
197+
IntValue: numaNodeIntPtr,
198+
},
199+
// PCIe Root Complex (upstream Kubernetes standard) - for topology-aware scheduling
200+
consts.AttributePCIeRoot: {
201+
StringValue: ptr.To(pfInfo.PCIeRoot),
202+
},
203+
// Immediate parent PCI address - for granular filtering
204+
consts.AttributeParentPciAddress: {
205+
StringValue: ptr.To(pfInfo.ParentPciAddress),
206+
},
207+
// Standard Kubernetes PCI address attribute
208+
consts.AttributeStandardPciAddress: {
209+
StringValue: ptr.To(vfInfo.PciAddress),
210+
},
211+
// Link type (ethernet, infiniband, etc.)
212+
consts.AttributeLinkType: {
213+
StringValue: ptr.To(pfInfo.LinkType),
214+
},
215+
consts.AttributeRDMACapable: {
216+
BoolValue: ptr.To(rdmaCapable),
217+
},
218+
}
219+
220+
resourceList[deviceName] = resourceapi.Device{
221+
Name: deviceName,
222+
Attributes: attributes,
208223
}
209224
}
210225
}

pkg/devicestate/discovery_test.go

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ var _ = Describe("DiscoverSriovDevices", func() {
7979
mockHost.EXPECT().GetParentPciAddress("0000:01:00.0").Return("0000:00:01.0", nil)
8080
mockHost.EXPECT().GetLinkType("0000:01:00.0").Return(consts.LinkTypeEthernet, nil)
8181
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(vfList, nil)
82+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.1").Return(false)
83+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.2").Return(false)
8284

8385
devices, err := DiscoverSriovDevices()
8486
Expect(err).NotTo(HaveOccurred())
@@ -153,7 +155,9 @@ var _ = Describe("DiscoverSriovDevices", func() {
153155
mockHost.EXPECT().GetLinkType("0000:02:00.0").Return(consts.LinkTypeInfiniband, nil)
154156

155157
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(vfList1, nil)
158+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.1").Return(false)
156159
mockHost.EXPECT().GetVFList("0000:02:00.0").Return(vfList2, nil)
160+
mockHost.EXPECT().VerifyRDMACapability("0000:02:00.1").Return(false)
157161

158162
devices, err := DiscoverSriovDevices()
159163
Expect(err).NotTo(HaveOccurred())
@@ -205,14 +209,15 @@ var _ = Describe("DiscoverSriovDevices", func() {
205209
mockHost.EXPECT().GetParentPciAddress("0000:01:00.0").Return("", nil)
206210
mockHost.EXPECT().GetLinkType("0000:01:00.0").Return(consts.LinkTypeEthernet, nil)
207211
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(vfList, nil)
212+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.1").Return(false)
208213

209214
devices, err := DiscoverSriovDevices()
210215
Expect(err).NotTo(HaveOccurred())
211216
Expect(devices).To(HaveLen(1))
212217

213-
// NUMA should default to 0
218+
// NUMA should default to -1 (not supported)
214219
dev := devices["0000-01-00-1"]
215-
Expect(dev.Attributes[consts.AttributeNumaNode].IntValue).To(Equal(ptr.To(int64(0))))
220+
Expect(dev.Attributes[consts.AttributeNumaNode].IntValue).To(Equal(ptr.To(int64(-1))))
216221
// Standard PCI address should still be set
217222
Expect(dev.Attributes[consts.AttributeStandardPciAddress].StringValue).To(Equal(ptr.To("0000:01:00.1")))
218223
})
@@ -242,6 +247,7 @@ var _ = Describe("DiscoverSriovDevices", func() {
242247
mockHost.EXPECT().GetParentPciAddress("0000:01:00.0").Return("", fmt.Errorf("parent not found"))
243248
mockHost.EXPECT().GetLinkType("0000:01:00.0").Return(consts.LinkTypeEthernet, nil)
244249
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(vfList, nil)
250+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.1").Return(false)
245251

246252
devices, err := DiscoverSriovDevices()
247253
Expect(err).NotTo(HaveOccurred())
@@ -279,6 +285,7 @@ var _ = Describe("DiscoverSriovDevices", func() {
279285
mockHost.EXPECT().GetParentPciAddress("0000:01:00.0").Return("0000:00:01.0", nil)
280286
mockHost.EXPECT().GetLinkType("0000:01:00.0").Return("", fmt.Errorf("lookup failed"))
281287
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(vfList, nil)
288+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.1").Return(false)
282289

283290
devices, err := DiscoverSriovDevices()
284291
Expect(err).NotTo(HaveOccurred())
@@ -292,6 +299,107 @@ var _ = Describe("DiscoverSriovDevices", func() {
292299
Expect(dev.Attributes[consts.AttributePFName].StringValue).To(Equal(ptr.To("eth0")))
293300
Expect(dev.Attributes[consts.AttributeStandardPciAddress].StringValue).To(Equal(ptr.To("0000:01:00.1")))
294301
})
302+
303+
Context("RDMA Capability", func() {
304+
var (
305+
pciInfo *pci.Info
306+
vfList []host.VFInfo
307+
)
308+
309+
BeforeEach(func() {
310+
pciInfo = &pci.Info{
311+
Devices: []*pci.Device{
312+
{
313+
Address: "0000:01:00.0",
314+
Class: &pcidb.Class{ID: "02"},
315+
Vendor: &pcidb.Vendor{ID: "15b3"}, // Mellanox
316+
Product: &pcidb.Product{ID: "1017"}, // ConnectX-5
317+
},
318+
},
319+
}
320+
321+
vfList = []host.VFInfo{
322+
{
323+
PciAddress: "0000:01:00.1",
324+
VFID: 0,
325+
DeviceID: "1018",
326+
},
327+
}
328+
329+
mockHost.EXPECT().PCI().Return(pciInfo, nil)
330+
mockHost.EXPECT().IsSriovVF("0000:01:00.0").Return(false)
331+
mockHost.EXPECT().TryGetInterfaceName("0000:01:00.0").Return("ib0")
332+
mockHost.EXPECT().GetNicSriovMode("0000:01:00.0").Return("switchdev")
333+
mockHost.EXPECT().GetNumaNode("0000:01:00.0").Return("1", nil)
334+
mockHost.EXPECT().GetPCIeRoot("0000:01:00.0").Return("pci0000:00", nil)
335+
mockHost.EXPECT().GetParentPciAddress("0000:01:00.0").Return("0000:00:01.0", nil)
336+
mockHost.EXPECT().GetLinkType("0000:01:00.0").Return(consts.LinkTypeInfiniband, nil)
337+
})
338+
339+
It("should discover RDMA-capable VFs with RDMA attributes", func() {
340+
// Add a second VF to the list for this specific test
341+
localVfList := []host.VFInfo{
342+
{
343+
PciAddress: "0000:01:00.1",
344+
VFID: 0,
345+
DeviceID: "1018",
346+
},
347+
{
348+
PciAddress: "0000:01:00.2",
349+
VFID: 1,
350+
DeviceID: "1018",
351+
},
352+
}
353+
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(localVfList, nil)
354+
355+
// First VF is RDMA-capable
356+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.1").Return(true)
357+
358+
// Second VF is not RDMA-capable
359+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.2").Return(false)
360+
361+
devices, err := DiscoverSriovDevices()
362+
Expect(err).NotTo(HaveOccurred())
363+
Expect(devices).To(HaveLen(2))
364+
365+
// Check first VF (RDMA-capable)
366+
dev1 := devices["0000-01-00-1"]
367+
Expect(dev1.Name).To(Equal("0000-01-00-1"))
368+
Expect(dev1.Attributes[consts.AttributeVendorID].StringValue).To(Equal(ptr.To("15b3")))
369+
Expect(dev1.Attributes[consts.AttributeDeviceID].StringValue).To(Equal(ptr.To("1018")))
370+
Expect(dev1.Attributes[consts.AttributePFDeviceID].StringValue).To(Equal(ptr.To("1017")))
371+
Expect(dev1.Attributes[consts.AttributePciAddress].StringValue).To(Equal(ptr.To("0000:01:00.1")))
372+
Expect(dev1.Attributes[consts.AttributePFName].StringValue).To(Equal(ptr.To("ib0")))
373+
Expect(dev1.Attributes[consts.AttributeEswitchMode].StringValue).To(Equal(ptr.To("switchdev")))
374+
Expect(dev1.Attributes[consts.AttributeVFID].IntValue).To(Equal(ptr.To(int64(0))))
375+
Expect(dev1.Attributes[consts.AttributeNumaNode].IntValue).To(Equal(ptr.To(int64(1))))
376+
Expect(dev1.Attributes[consts.AttributePCIeRoot].StringValue).To(Equal(ptr.To("pci0000:00")))
377+
Expect(dev1.Attributes[consts.AttributeParentPciAddress].StringValue).To(Equal(ptr.To("0000:00:01.0")))
378+
Expect(dev1.Attributes[consts.AttributeStandardPciAddress].StringValue).To(Equal(ptr.To("0000:01:00.1")))
379+
// RDMA-specific attributes
380+
Expect(dev1.Attributes[consts.AttributeRDMACapable].BoolValue).To(Equal(ptr.To(true)))
381+
382+
// Check second VF (not RDMA-capable)
383+
dev2 := devices["0000-01-00-2"]
384+
Expect(dev2.Name).To(Equal("0000-01-00-2"))
385+
Expect(dev2.Attributes[consts.AttributeVFID].IntValue).To(Equal(ptr.To(int64(1))))
386+
Expect(dev2.Attributes[consts.AttributeRDMACapable].BoolValue).To(Equal(ptr.To(false)))
387+
})
388+
389+
It("should handle RDMA capability check errors gracefully", func() {
390+
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(vfList, nil)
391+
// RDMA capability check fails (returns false)
392+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.1").Return(false)
393+
394+
devices, err := DiscoverSriovDevices()
395+
Expect(err).NotTo(HaveOccurred())
396+
Expect(devices).To(HaveLen(1))
397+
398+
// Should default to not RDMA capable
399+
dev := devices["0000-01-00-1"]
400+
Expect(dev.Attributes[consts.AttributeRDMACapable].BoolValue).To(Equal(ptr.To(false)))
401+
})
402+
})
295403
})
296404

297405
Context("Filtering Cases", func() {
@@ -355,6 +463,7 @@ var _ = Describe("DiscoverSriovDevices", func() {
355463
mockHost.EXPECT().GetParentPciAddress("0000:01:00.0").Return("", nil)
356464
mockHost.EXPECT().GetLinkType("0000:01:00.0").Return(consts.LinkTypeEthernet, nil)
357465
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(vfList, nil)
466+
mockHost.EXPECT().VerifyRDMACapability("0000:01:00.1").Return(false)
358467

359468
// Second device (VF) - should be skipped
360469
mockHost.EXPECT().IsSriovVF("0000:01:00.1").Return(true)
@@ -486,6 +595,7 @@ var _ = Describe("DiscoverSriovDevices", func() {
486595
mockHost.EXPECT().GetParentPciAddress("0000:01:00.0").Return("", nil)
487596
mockHost.EXPECT().GetLinkType("0000:01:00.0").Return(consts.LinkTypeEthernet, nil)
488597
mockHost.EXPECT().GetVFList("0000:01:00.0").Return(vfList, nil)
598+
mockHost.EXPECT().VerifyRDMACapability("0000:af:10.7").Return(false)
489599

490600
devices, err := DiscoverSriovDevices()
491601
Expect(err).NotTo(HaveOccurred())

0 commit comments

Comments
 (0)