-
Notifications
You must be signed in to change notification settings - Fork 182
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sriov: add support as special PCI devices
Add support to report SRIOV devices. Differently from GPU devices, we model SRIOV devices as special PCI devices, extending the `pci` package instead of introducing a new top-level package. This design emerged during the review of a previous proposal: 9058f61#r755312597 SRIOV devices are either Physical Functions or Virtual functions. The preferred representation for ghw is Physical Functions, whose dependent devices will be Virtual Functions; however, for the sake of practicality, the API also exposes soft references to Virtual Functions, so consumers of the API can access them directly and not navigating the parent devices. This patch also adds support in `ghwc`, to report the sriov information, and in the `snapshot` package, to make sure to capture all the files in sysfs that ghw cares about. Last but not least, lacking access to suitable non-linux systems, support is provided only on linux OS, even though the API tries hard not to be linux-specific. Resolves: #92 Signed-off-by: Francesco Romani <fromani@redhat.com>
- Loading branch information
Showing
10 changed files
with
315 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package commands | ||
|
||
import ( | ||
"github.com/jaypipes/ghw" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// sriovCmd represents the install command | ||
var sriovCmd = &cobra.Command{ | ||
Use: "sriov", | ||
Short: "Show Single Root I/O Virtualization device information for the host system", | ||
RunE: showSRIOV, | ||
} | ||
|
||
// showSRIOV shows SRIOV information for the host system. | ||
func showSRIOV(cmd *cobra.Command, args []string) error { | ||
info, err := ghw.PCI() | ||
if err != nil { | ||
return errors.Wrap(err, "error getting SRIOV info through PCI") | ||
} | ||
|
||
printInfo(info.DescribeDevices(info.GetSRIOVDevices())) | ||
return nil | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(sriovCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package pci | ||
|
||
import "fmt" | ||
|
||
// Function describes an SR-IOV physical or virtual function. Physical functions | ||
// will have no Parent Function struct pointer and will have one or more Function | ||
// structs in the Virtual field. | ||
type Function struct { | ||
Parent *Function `json:"parent,omitempty"` | ||
// MaxVirtual contains the maximum number of supported virtual | ||
// functions for this physical function | ||
MaxVirtual int `json:"max_virtual,omitempty"` | ||
// Virtual contains the physical function's virtual functions | ||
Virtual []*Function `json:"virtual_functions"` | ||
} | ||
|
||
// IsPhysical returns true if the PCIe function is a physical function, false | ||
// if it is a virtual function. It is safe to assume that if a function is not | ||
// physical, then is virtual (e.g. can't be anything else) | ||
func (f *Function) IsPhysical() bool { | ||
return f.Parent == nil | ||
} | ||
|
||
func (f *Function) String() string { | ||
if f.IsPhysical() { | ||
return fmt.Sprintf("function: 'physical' virtual: '%d/%d'", len(f.Virtual), f.MaxVirtual) | ||
} | ||
return "function: 'virtual'" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package pci | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/jaypipes/ghw/pkg/linuxpath" | ||
"github.com/jaypipes/ghw/pkg/util" | ||
) | ||
|
||
// GetSRIOVDevices returns only the PCI devices that are | ||
// Single Root I/O Virtualization (SR-IOV) capable -- either | ||
// physical of virtual functions. | ||
func (i *Info) GetSRIOVDevices() []*Device { | ||
res := []*Device{} | ||
for _, dev := range i.Devices { | ||
if dev.Function == nil { | ||
continue | ||
} | ||
res = append(res, dev) | ||
} | ||
return res | ||
} | ||
|
||
func (info *Info) fillSRIOVDevices() error { | ||
for _, dev := range info.Devices { | ||
isPF, err := info.fillPhysicalFunctionForDevice(dev) | ||
if !isPF { | ||
// not a physical function, nothing to do | ||
continue | ||
} | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (info *Info) fillPhysicalFunctionForDevice(dev *Device) (bool, error) { | ||
paths := linuxpath.New(info.ctx) | ||
devPath := filepath.Join(paths.SysBusPciDevices, dev.Address) | ||
|
||
buf, err := os.ReadFile(filepath.Join(devPath, "sriov_totalvfs")) | ||
if err != nil { | ||
// is not a physfn. Since we will fill virtfn from physfn, we can give up now | ||
// note we intentionally swallow the error. | ||
return false, nil | ||
} | ||
|
||
maxVFs, err := strconv.Atoi(strings.TrimSpace(string(buf))) | ||
if err != nil { | ||
return true, fmt.Errorf("cannot reading sriov_totalvfn: %w", err) | ||
} | ||
|
||
pf := &Function{ | ||
MaxVirtual: maxVFs, | ||
} | ||
err = info.fillVirtualFunctionsForPhysicalFunction(pf, devPath) | ||
if err != nil { | ||
return true, fmt.Errorf("cannot inspect VFs: %w", err) | ||
} | ||
dev.Function = pf | ||
return true, nil | ||
} | ||
|
||
func (info *Info) fillVirtualFunctionsForPhysicalFunction(parentFn *Function, parentPath string) error { | ||
numVfs := util.SafeIntFromFile(info.ctx, filepath.Join(parentPath, "sriov_numvfs")) | ||
if numVfs == -1 { | ||
return fmt.Errorf("invalid number of virtual functions: %v", numVfs) | ||
} | ||
|
||
var vfs []*Function | ||
for vfnIdx := 0; vfnIdx < numVfs; vfnIdx++ { | ||
virtFn := fmt.Sprintf("virtfn%d", vfnIdx) | ||
vfnDest, err := os.Readlink(filepath.Join(parentPath, virtFn)) | ||
if err != nil { | ||
return fmt.Errorf("error reading backing device for virtfn %q: %w", virtFn, err) | ||
} | ||
|
||
vfnAddr := filepath.Base(vfnDest) | ||
vfnDev := info.GetDevice(vfnAddr) | ||
if vfnDev == nil { | ||
return fmt.Errorf("error finding the PCI device for virtfn %s", vfnAddr) | ||
} | ||
|
||
// functions must be ordered by their index | ||
vf := &Function{ | ||
Parent: parentFn, | ||
} | ||
|
||
vfs = append(vfs, vf) | ||
vfnDev.Function = vf | ||
} | ||
|
||
parentFn.Virtual = vfs | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//go:build !linux | ||
// +build !linux | ||
|
||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package pci | ||
|
||
func (i *Info) GetSRIOVDevices() []*Device { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.