aboutsummaryrefslogtreecommitdiff
path: root/packages/numap/internal/sysfs/pci.go
diff options
context:
space:
mode:
Diffstat (limited to 'packages/numap/internal/sysfs/pci.go')
-rw-r--r--packages/numap/internal/sysfs/pci.go145
1 files changed, 145 insertions, 0 deletions
diff --git a/packages/numap/internal/sysfs/pci.go b/packages/numap/internal/sysfs/pci.go
new file mode 100644
index 0000000..9e714b1
--- /dev/null
+++ b/packages/numap/internal/sysfs/pci.go
@@ -0,0 +1,145 @@
+package sysfs
+
+import (
+ "fmt"
+ "io/ioutil"
+ "path"
+ "path/filepath"
+ "strconv"
+ "strings"
+)
+
+const (
+ sysFsPCIDevicesPath = "/sys/bus/pci/devices/"
+)
+
+type PCIDevice struct {
+ NumaNode int
+ ID string
+ Device, Vendor uint64
+ SubVendor, SubDevice uint64
+ Class uint64
+ MSIs []int
+}
+
+func ScanPCIDevices() []PCIDevice {
+ devices, err := ioutil.ReadDir(sysFsPCIDevicesPath)
+ if err != nil {
+ panic(err)
+ }
+
+ pciDevices := []PCIDevice{}
+
+ for _, device := range devices {
+ dpath := filepath.Join(sysFsPCIDevicesPath, device.Name())
+ pcid, err := NewPCIDevice(dpath, device.Name())
+ if err != nil {
+ panic(err)
+ }
+ pciDevices = append(pciDevices, pcid)
+ }
+ return pciDevices
+}
+
+func getPCIDeviceClass(path string) (uint64, error) {
+ return ContentUint64(filepath.Join(path, "class"))
+}
+
+func getPCIDeviceVendor(path string) (uint64, error) {
+ return ContentUint64(filepath.Join(path, "vendor"))
+}
+
+func getPCIDeviceId(path string) (uint64, error) {
+ return ContentUint64(filepath.Join(path, "device"))
+}
+
+func getPCIDeviceSubsystemDevice(path string) (uint64, error) {
+ return ContentUint64(filepath.Join(path, "subsystem_device"))
+}
+
+func getPCIDeviceSubsystemVendor(path string) (uint64, error) {
+ return ContentUint64(filepath.Join(path, "subsystem_vendor"))
+}
+
+func getPCIDeviceNumaNode(path string) int {
+ content, err := ioutil.ReadFile(filepath.Join(path, "numa_node"))
+ if err != nil {
+ panic(err)
+ }
+ nodeNum, err := strconv.Atoi(strings.TrimSpace(string(content)))
+ if err != nil {
+ panic(err)
+ }
+ return nodeNum
+}
+
+func getPCIDeviceMSIx(p string) []int {
+ g := fmt.Sprintf("%s/*", filepath.Join(p, "msi_irqs"))
+ files, err := filepath.Glob(g)
+ if err != nil {
+ panic(err)
+ }
+ if len(files) == 0 {
+ return []int{}
+ }
+
+ msix := []int{}
+
+ for _, f := range files {
+ content, err := ioutil.ReadFile(f)
+ if err != nil {
+ panic(err)
+ }
+ if strings.TrimSpace(string(content)) == "msix" {
+ base := path.Base(f)
+ v, err := strconv.Atoi(base)
+ if err != nil {
+ panic(err)
+ }
+ msix = append(msix, v)
+ }
+ }
+ return msix
+}
+
+func NewPCIDevice(path, name string) (PCIDevice, error) {
+ nodeNum := getPCIDeviceNumaNode(path)
+
+ device, err := getPCIDeviceId(path)
+ if err != nil {
+ return PCIDevice{}, err
+ }
+
+ vendor, err := getPCIDeviceVendor(path)
+ if err != nil {
+ return PCIDevice{}, err
+ }
+
+ subvendor, err := getPCIDeviceSubsystemVendor(path)
+ if err != nil {
+ return PCIDevice{}, err
+ }
+
+ subdevice, err := getPCIDeviceSubsystemDevice(path)
+ if err != nil {
+ return PCIDevice{}, err
+ }
+
+ deviceClass, err := getPCIDeviceClass(path)
+ if err != nil {
+ return PCIDevice{}, err
+ }
+
+ msix := getPCIDeviceMSIx(path)
+
+ return PCIDevice{
+ ID: name,
+ Device: device,
+ Class: deviceClass,
+ NumaNode: nodeNum,
+ Vendor: vendor,
+ SubVendor: subvendor,
+ SubDevice: subdevice,
+ MSIs: msix,
+ }, nil
+}