-
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.
WIP patch to demonstrate the possible API TBD: add tests TBD: provide rationale in the commit message Signed-off-by: Francesco Romani <fromani@redhat.com>
- Loading branch information
Showing
8 changed files
with
237 additions
and
0 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
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 |
---|---|---|
|
@@ -22,6 +22,7 @@ type pciTestCase struct { | |
addr string | ||
node int | ||
revision string | ||
isSRIOV bool | ||
} | ||
|
||
// nolint: gocyclo | ||
|
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,28 @@ | ||
// | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package pci | ||
|
||
type VFInfo struct { | ||
ID int `json:"id"` | ||
PCIAddress string `json:"pci_address"` | ||
} | ||
|
||
type SRIOVPhysFn struct { | ||
MaxVFNum int `json:"max_vf_num"` | ||
VFs []VFInfo `json:"vfs"` | ||
} | ||
|
||
type SRIOVVirtFn struct { | ||
ParentPCIAddress string `json:"parent_pci_address"` | ||
} | ||
|
||
type SRIOVInfo struct { | ||
Driver string `json:"driver"` | ||
Interfaces []string `json:"interfaces"` | ||
PhysFn *SRIOVPhysFn `json:"physfn,omitempty"` | ||
VirtFn *SRIOVVirtFn `json:"virtfn,omitempty"` | ||
} |
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,104 @@ | ||
// 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" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/jaypipes/ghw/pkg/context" | ||
"github.com/jaypipes/ghw/pkg/linuxpath" | ||
"github.com/jaypipes/ghw/pkg/util" | ||
) | ||
|
||
func getDeviceSriovInfo(ctx *context.Context, address string) *SRIOVInfo { | ||
paths := linuxpath.New(ctx) | ||
pciAddr := AddressFromString(address) | ||
if pciAddr == nil { | ||
return nil | ||
} | ||
devPath := filepath.Join(paths.SysBusPciDevices, pciAddr.String()) | ||
|
||
// see: https://doc.dpdk.org/guides/linux_gsg/linux_drivers.html | ||
driver := "" | ||
if dest, err := os.Readlink(filepath.Join(devPath, "driver")); err == nil { | ||
driver = filepath.Base(dest) | ||
} | ||
|
||
if dest, err := os.Readlink(filepath.Join(devPath, "physfn")); err == nil { | ||
// it's a virtual function! | ||
return &SRIOVInfo{ | ||
Driver: driver, | ||
Interfaces: findNetworks(ctx, devPath), | ||
VirtFn: &SRIOVVirtFn{ | ||
ParentPCIAddress: filepath.Base(dest), | ||
}, | ||
} | ||
} | ||
// it's either a physical function or a non-SRIOV device | ||
if buf, err := ioutil.ReadFile(filepath.Join(devPath, "sriov_totalvfs")); err == nil { | ||
// it seems a physical function | ||
maxVFs, err := strconv.Atoi(strings.TrimSpace(string(buf))) | ||
if err != nil { | ||
ctx.Warn("error reading sriov_totalvfn for %q: %v", err) | ||
return nil | ||
} | ||
|
||
return &SRIOVInfo{ | ||
Driver: driver, | ||
Interfaces: findNetworks(ctx, devPath), | ||
PhysFn: &SRIOVPhysFn{ | ||
MaxVFNum: maxVFs, | ||
VFs: findVFsFromPF(ctx, devPath), | ||
}, | ||
} | ||
} | ||
// not a SRIOV device | ||
return nil | ||
} | ||
|
||
func findNetworks(ctx *context.Context, devPath string) []string { | ||
netPath := filepath.Join(devPath, "net") | ||
|
||
netEntries, err := ioutil.ReadDir(netPath) | ||
if err != nil { | ||
ctx.Warn("cannot enumerate network names for %q: %v", devPath, err) | ||
return nil | ||
} | ||
|
||
var networks []string | ||
for _, netEntry := range netEntries { | ||
networks = append(networks, netEntry.Name()) | ||
} | ||
|
||
return networks | ||
} | ||
|
||
func findVFsFromPF(ctx *context.Context, devPath string) []VFInfo { | ||
numVfs := util.SafeIntFromFile(ctx, filepath.Join(devPath, "sriov_numvfs")) | ||
if numVfs == -1 { | ||
return nil | ||
} | ||
|
||
var vfs []VFInfo | ||
for vfnIdx := 0; vfnIdx < numVfs; vfnIdx++ { | ||
virtFn := fmt.Sprintf("virtfn%d", vfnIdx) | ||
vfnDest, err := os.Readlink(filepath.Join(devPath, virtFn)) | ||
if err != nil { | ||
ctx.Warn("error reading backing device for virtfn %q physfn %q: %v", virtFn, devPath, err) | ||
return nil | ||
} | ||
vfs = append(vfs, VFInfo{ | ||
ID: vfnIdx, | ||
PCIAddress: filepath.Base(vfnDest), | ||
}) | ||
} | ||
return vfs | ||
} |
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,48 @@ | ||
// | ||
// Use and distribution licensed under the Apache license version 2. | ||
// | ||
// See the COPYING file in the root project directory for full text. | ||
// | ||
|
||
package pci_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
) | ||
|
||
// nolint: gocyclo | ||
func TestPCICrosscheckSRIOV(t *testing.T) { | ||
info := pciTestSetup(t) | ||
|
||
tCases := []pciTestCase{ | ||
{ | ||
addr: "0000:07:03.0", | ||
isSRIOV: false, | ||
}, | ||
{ | ||
addr: "0000:05:11.0", | ||
isSRIOV: true, | ||
}, | ||
{ | ||
addr: "0000:05:00.1", | ||
isSRIOV: true, | ||
}, | ||
} | ||
for _, tCase := range tCases { | ||
t.Run(fmt.Sprintf("%s (sriov=%v)", tCase.addr, tCase.isSRIOV), func(t *testing.T) { | ||
dev := info.GetDevice(tCase.addr) | ||
if dev == nil { | ||
t.Fatalf("got nil device for address %q", tCase.addr) | ||
} | ||
sriovInfo := info.GetSRIOVInfo(tCase.addr) | ||
if tCase.isSRIOV && sriovInfo == nil { | ||
t.Fatalf("expected SRIOV info for device at address %q", tCase.addr) | ||
} | ||
if !tCase.isSRIOV && sriovInfo != nil { | ||
t.Fatalf("unexpected SRIOV info for device at address %q", tCase.addr) | ||
} | ||
}) | ||
} | ||
|
||
} |
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
Binary file modified
BIN
+1.79 KB
(100%)
testdata/snapshots/linux-amd64-8581cf3a529e5d8b97ea876eade2f60d.tar.gz
Binary file not shown.