Skip to content

Commit 218cf28

Browse files
authored
Merge pull request #682 from adrianchiris/add-vhostnet-to-sf
Add vhostnet to sf
2 parents b73244e + 3a2cae6 commit 218cf28

File tree

6 files changed

+164
-20
lines changed

6 files changed

+164
-20
lines changed

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,14 +348,15 @@ These selectors are applicable when "deviceType" is "auxNetDevice".
348348

349349
| Field | Required | Description | Type/Defaults | Example/Accepted values |
350350
|---------------|----------|----------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|--------------------------------------------------------------------------------------------------|
351-
| "vendors" | N | Target device's vendor Hex code as string | `string` list Default: `null` | "vendors": ["8086", "15b3"] |
352-
| "devices" | N | Parent PCI device Hex code as string | `string` list Default: `null` | "devices": ["154c", "1889", "1018"] |
353-
| "drivers" | N | Target device driver names as string | `string` list Default: `null` | "drivers": ["vfio-pci"] |
354-
| "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") |
355-
| "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") |
356-
| "linkTypes" | N | The link type of the net device associated with the PCI device | `string` list Default: `null` | "linkTypes": ["ether"] |
357-
| "isRdma" | N | Mount RDMA resources. Incompatible with vdpaType | `bool` values `true` or `false` Default: `false` | "isRdma": `true` |
358-
| "auxTypes" | N | List of vendor specific auxiliary network device types. Device type can be determined by its name: <driver_name>.<kind_of_a_type>.<id> | `string` list Default: `null` | "auxTypes": ["sf", "eth"] |
351+
| "vendors" | N | Target device's vendor Hex code as string | `string` list Default: `null` | "vendors": ["8086", "15b3"] |
352+
| "devices" | N | Parent PCI device Hex code as string | `string` list Default: `null` | "devices": ["154c", "1889", "1018"] |
353+
| "drivers" | N | Target device driver names as string | `string` list Default: `null` | "drivers": ["vfio-pci"] |
354+
| "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") |
355+
| "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") |
356+
| "linkTypes" | N | The link type of the net device associated with the PCI device | `string` list Default: `null` | "linkTypes": ["ether"] |
357+
| "isRdma" | N | Mount RDMA resources. Incompatible with vdpaType | `bool` values `true` or `false` Default: `false` | "isRdma": `true` |
358+
| "needVhostNet" | N | Share /dev/vhost-net and /dev/net/tun | `bool` values `true` or `false` Default: `false` | "needVhostNet": `true` |
359+
| "auxTypes" | N | List of vendor-specific auxiliary network device types. Device type can be determined by its name: <driver_name>.<kind_of_a_type>.<id> | `string` list Default: `null` | "auxTypes": ["sf", "eth"] |
359360

360361
[//]: # (The tables above generated using: https://ozh.github.io/ascii-tables/)
361362

pkg/auxnetdevice/auxNetDevice.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ func NewAuxNetDevice(dev *ghw.PCIDevice, deviceID string, rFactory types.Resourc
6565
glog.Warningf("RDMA resources for %s not found. Are RDMA modules loaded?", deviceID)
6666
}
6767
}
68+
69+
if nf.NeedVhostNet {
70+
if infoprovider.VhostNetDeviceExist() {
71+
infoProviders = append(infoProviders, infoprovider.NewVhostNetInfoProvider())
72+
} else {
73+
glog.Warningf("vhost-net is required in the configuration for %s but /dev/vhost-net doesn't exist", deviceID)
74+
}
75+
}
6876
}
6977

7078
hostDev, err := devices.NewHostDeviceImpl(dev, deviceID, rFactory, rc, infoProviders)

pkg/auxnetdevice/auxNetDevice_test.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package auxnetdevice_test
1919

2020
import (
21+
"path/filepath"
2122
"testing"
2223

2324
"github.com/jaypipes/ghw"
@@ -28,6 +29,7 @@ import (
2829

2930
"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/auxnetdevice"
3031
"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/factory"
32+
"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/infoprovider"
3133
"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types"
3234
tmocks "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types/mocks"
3335
"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/utils"
@@ -299,5 +301,137 @@ var _ = Describe("AuxNetDevice", func() {
299301
fakeSriovnetProvider.AssertExpectations(t)
300302
})
301303
})
304+
305+
Context("with needVhostNet", func() {
306+
It("should provide expected environment variables and mounts", func() {
307+
fs := &utils.FakeFilesystem{
308+
Dirs: []string{
309+
"sys/bus/pci/devices/0000:00:00.1/net/net0",
310+
"sys/bus/pci/drivers/mlx5_core",
311+
"dev/net/tun",
312+
"dev/vhost-net",
313+
},
314+
Symlinks: map[string]string{
315+
"sys/bus/pci/devices/0000:00:00.1/driver": "../../../../bus/pci/drivers/mlx5_core",
316+
},
317+
Files: map[string][]byte{"sys/bus/pci/devices/0000:00:00.1/numa_node": []byte("0")},
318+
}
319+
defer fs.Use()()
320+
321+
infoprovider.HostNet = filepath.Join(fs.RootDir, "dev/vhost-net")
322+
infoprovider.HostTun = filepath.Join(fs.RootDir, "dev/net/tun")
323+
324+
utils.SetDefaultMockNetlinkProvider()
325+
auxDevID := "mlx5_core.sf.0"
326+
fakeSriovnetProvider := mocks.SriovnetProvider{}
327+
fakeSriovnetProvider.
328+
On("GetUplinkRepresentorFromAux", auxDevID).Return("net0", nil).
329+
On("GetPfPciFromAux", auxDevID).Return("0000:00:00.1", nil).
330+
On("GetSfIndexByAuxDev", auxDevID).Return(1, nil).
331+
On("GetNetDevicesFromAux", auxDevID).Return([]string{"eth0"}, nil)
332+
utils.SetSriovnetProviderInst(&fakeSriovnetProvider)
333+
334+
f := factory.NewResourceFactory("fake", "fake", true, false)
335+
in := newPciDevice("0000:00:00.1")
336+
rc := &types.ResourceConfig{
337+
ResourceName: "fake",
338+
ResourcePrefix: "fake",
339+
DeviceType: types.AuxNetDeviceType,
340+
SelectorObjs: []interface{}{&types.AuxNetDeviceSelectors{
341+
GenericNetDeviceSelectors: types.GenericNetDeviceSelectors{
342+
NeedVhostNet: true,
343+
},
344+
}}}
345+
346+
dev, err := auxnetdevice.NewAuxNetDevice(in, auxDevID, f, rc, 0)
347+
Expect(err).NotTo(HaveOccurred())
348+
Expect(dev).NotTo(BeNil())
349+
Expect(dev.GetDriver()).To(Equal("mlx5_core"))
350+
Expect(dev.GetNetName()).To(Equal("eth0"))
351+
352+
envs := dev.GetEnvVal()
353+
Expect(envs).To(HaveLen(2))
354+
// validate device ID env var
355+
Expect(envs).To(HaveKey("generic"))
356+
Expect(envs["generic"]).To(HaveKeyWithValue("deviceID", "mlx5_core.sf.0"))
357+
// validate vhost env vars
358+
Expect(envs).To(HaveKey("vhost"))
359+
Expect(envs["vhost"]).To(HaveKeyWithValue("net-mount", "/dev/vhost-net"))
360+
Expect(envs["vhost"]).To(HaveKeyWithValue("tun-mount", "/dev/net/tun"))
361+
362+
// validate mounts
363+
devSpecs := dev.GetDeviceSpecs()
364+
Expect(devSpecs).To(HaveLen(2))
365+
Expect(devSpecs).To(ConsistOf(
366+
And(HaveField("HostPath", "/dev/vhost-net"), HaveField("ContainerPath", "/dev/vhost-net")),
367+
And(HaveField("HostPath", "/dev/net/tun"), HaveField("ContainerPath", "/dev/net/tun")),
368+
))
369+
370+
Expect(dev.GetLinkType()).To(Equal("fakeLinkType"))
371+
Expect(dev.GetFuncID()).To(Equal(1))
372+
Expect(dev.GetAPIDevice().Topology.Nodes[0].ID).To(Equal(int64(0)))
373+
Expect(dev.GetAuxType()).To(Equal("sf"))
374+
fakeSriovnetProvider.AssertExpectations(t)
375+
})
376+
377+
It("should not contain vhost related environment variables and mounts if vhost-net device does not exist", func() {
378+
fs := &utils.FakeFilesystem{
379+
Dirs: []string{
380+
"sys/bus/pci/devices/0000:00:00.1/net/net0",
381+
"sys/bus/pci/drivers/mlx5_core",
382+
},
383+
Symlinks: map[string]string{
384+
"sys/bus/pci/devices/0000:00:00.1/driver": "../../../../bus/pci/drivers/mlx5_core",
385+
},
386+
Files: map[string][]byte{"sys/bus/pci/devices/0000:00:00.1/numa_node": []byte("0")},
387+
}
388+
defer fs.Use()()
389+
390+
infoprovider.HostNet = filepath.Join(fs.RootDir, "dev/vhost-net")
391+
infoprovider.HostTun = filepath.Join(fs.RootDir, "dev/net/tun")
392+
393+
utils.SetDefaultMockNetlinkProvider()
394+
auxDevID := "mlx5_core.sf.0"
395+
fakeSriovnetProvider := mocks.SriovnetProvider{}
396+
fakeSriovnetProvider.
397+
On("GetUplinkRepresentorFromAux", auxDevID).Return("net0", nil).
398+
On("GetPfPciFromAux", auxDevID).Return("0000:00:00.1", nil).
399+
On("GetSfIndexByAuxDev", auxDevID).Return(1, nil).
400+
On("GetNetDevicesFromAux", auxDevID).Return([]string{"eth0"}, nil)
401+
utils.SetSriovnetProviderInst(&fakeSriovnetProvider)
402+
403+
f := factory.NewResourceFactory("fake", "fake", true, false)
404+
in := newPciDevice("0000:00:00.1")
405+
rc := &types.ResourceConfig{
406+
ResourceName: "fake",
407+
ResourcePrefix: "fake",
408+
DeviceType: types.AuxNetDeviceType,
409+
SelectorObjs: []interface{}{&types.AuxNetDeviceSelectors{
410+
GenericNetDeviceSelectors: types.GenericNetDeviceSelectors{
411+
NeedVhostNet: true,
412+
},
413+
}}}
414+
415+
dev, err := auxnetdevice.NewAuxNetDevice(in, auxDevID, f, rc, 0)
416+
Expect(err).NotTo(HaveOccurred())
417+
Expect(dev).NotTo(BeNil())
418+
Expect(dev.GetDriver()).To(Equal("mlx5_core"))
419+
Expect(dev.GetNetName()).To(Equal("eth0"))
420+
421+
envs := dev.GetEnvVal()
422+
Expect(envs).To(HaveLen(1))
423+
// validate device ID env var
424+
Expect(envs).To(HaveKey("generic"))
425+
Expect(envs["generic"]).To(HaveKeyWithValue("deviceID", "mlx5_core.sf.0"))
426+
427+
// validate no mounts
428+
Expect(dev.GetDeviceSpecs()).To(BeEmpty())
429+
Expect(dev.GetLinkType()).To(Equal("fakeLinkType"))
430+
Expect(dev.GetFuncID()).To(Equal(1))
431+
Expect(dev.GetAPIDevice().Topology.Nodes[0].ID).To(Equal(int64(0)))
432+
Expect(dev.GetAuxType()).To(Equal("sf"))
433+
fakeSriovnetProvider.AssertExpectations(t)
434+
})
435+
})
302436
})
303437
})

pkg/netdevice/pciNetDevice.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func NewPciNetDevice(dev *ghw.PCIDevice,
7878
if infoprovider.VhostNetDeviceExist() {
7979
infoProviders = append(infoProviders, infoprovider.NewVhostNetInfoProvider())
8080
} else {
81-
glog.Errorf("GetDeviceSpecs(): vhost-net is required in the configuration but /dev/vhost-net doesn't exist")
81+
glog.Warningf("vhost-net is required in the configuration for %s but /dev/vhost-net doesn't exist", dev.Address)
8282
}
8383
}
8484
}

pkg/netdevice/pciNetDevice_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,9 @@ var _ = Describe("PciNetDevice", func() {
244244
ResourcePrefix: "fake",
245245
SelectorObjs: []interface{}{&types.NetDeviceSelectors{},
246246
&types.NetDeviceSelectors{
247-
NeedVhostNet: true,
248-
},
247+
GenericNetDeviceSelectors: types.GenericNetDeviceSelectors{
248+
NeedVhostNet: true,
249+
}},
249250
}}
250251
no_vhost_net_selector_index := 0
251252
vhost_net_selector_index := 1

pkg/types/types.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,22 +122,22 @@ type GenericPciDeviceSelectors struct {
122122

123123
// GenericNetDeviceSelectors contains common net device selectors fields
124124
type GenericNetDeviceSelectors struct {
125-
PfNames []string `json:"pfNames,omitempty"`
126-
RootDevices []string `json:"rootDevices,omitempty"`
127-
LinkTypes []string `json:"linkTypes,omitempty"`
128-
IsRdma bool // the resource support rdma
129-
AcpiIndexes []string `json:"acpiIndexes,omitempty"`
125+
PfNames []string `json:"pfNames,omitempty"`
126+
RootDevices []string `json:"rootDevices,omitempty"`
127+
LinkTypes []string `json:"linkTypes,omitempty"`
128+
IsRdma bool // the resource support rdma
129+
AcpiIndexes []string `json:"acpiIndexes,omitempty"`
130+
NeedVhostNet bool `json:"needVhostNet,omitempty"` // share vhost-net along the selected resource
130131
}
131132

132133
// NetDeviceSelectors contains network device related selectors fields
133134
type NetDeviceSelectors struct {
134135
DeviceSelectors
135136
GenericPciDeviceSelectors
136137
GenericNetDeviceSelectors
137-
DDPProfiles []string `json:"ddpProfiles,omitempty"`
138-
NeedVhostNet bool // share vhost-net along the selected resource
139-
VdpaType VdpaType `json:"vdpaType,omitempty"`
140-
PKeys []string `json:"pKeys,omitempty"`
138+
DDPProfiles []string `json:"ddpProfiles,omitempty"`
139+
VdpaType VdpaType `json:"vdpaType,omitempty"`
140+
PKeys []string `json:"pKeys,omitempty"`
141141
}
142142

143143
// AccelDeviceSelectors contains accelerator(FPGA etc.) related selectors fields

0 commit comments

Comments
 (0)