fix(pcie): account for downstream link capability

This commit is contained in:
Mikhail Chusavitin
2026-08-28 09:12:02 +03:00
parent af95216c6f
commit 2354599889
2 changed files with 205 additions and 15 deletions
@@ -1,6 +1,8 @@
package platform
import (
"os"
"path/filepath"
"strings"
"testing"
)
@@ -30,6 +32,82 @@ func TestClassifyGPUFromVendorClass(t *testing.T) {
}
}
func TestPCIeBridgeUsesDownstreamCapability(t *testing.T) {
cases := []struct {
name string
portSpeed string
portWidth int
endpointSpeed string
endpointWidth int
wantSpeed string
wantWidth int
}{
{"ConnectX-5 behind Gen4 root port", "Gen4", 16, "Gen3", 8, "Gen3", 8},
{"Adaptec SAS behind Gen4 root port", "Gen4", 16, "Gen3", 8, "Gen3", 8},
{"I350 behind Gen4 root port", "Gen4", 16, "Gen2", 4, "Gen2", 4},
{"faster endpoint remains port-limited", "Gen3", 8, "Gen4", 16, "Gen3", 8},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
gotSpeed := minPCIeLinkSpeed(tc.portSpeed, tc.endpointSpeed)
gotWidth := minPositiveInt(tc.portWidth, tc.endpointWidth)
if gotSpeed != tc.wantSpeed || gotWidth != tc.wantWidth {
t.Fatalf("effective capability = %s x%d, want %s x%d", gotSpeed, gotWidth, tc.wantSpeed, tc.wantWidth)
}
})
}
}
func TestPCIeBridgeAtEndpointMaximumPasses(t *testing.T) {
maxSpeed := minPCIeLinkSpeed("Gen4", "Gen3")
maxWidth := minPositiveInt(16, 8)
finding := pcieLinkFinding{
BDF: "0000:4a:02.0",
Description: "Intel root port to ConnectX-5",
BeforeSpeed: "Gen3",
AfterSpeed: "Gen3",
MaxSpeed: maxSpeed,
PortMaxSpeed: "Gen4",
Width: 8,
MaxWidth: maxWidth,
PortMaxWidth: 16,
Degraded: "Gen3" != maxSpeed,
}
summary := renderPCIeLinkCheckSummary([]pcieLinkFinding{finding})
if !strings.Contains(summary, "overall_status=OK") {
t.Fatalf("endpoint-limited bridge should pass, got:\n%s", summary)
}
report := renderPCIeLinkCheckReport([]pcieLinkFinding{finding})
if !strings.Contains(report, "limited by downstream device") {
t.Fatalf("report should explain the effective maximum, got:\n%s", report)
}
}
func TestDownstreamPCIeLinkCapabilityFromSysfsTopology(t *testing.T) {
bridgeDir := t.TempDir()
childDir := filepath.Join(bridgeDir, "0000:4b:00.0")
if err := os.Mkdir(childDir, 0755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(childDir, "max_link_speed"), []byte("8.0 GT/s PCIe\n"), 0644); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(childDir, "max_link_width"), []byte("8\n"), 0644); err != nil {
t.Fatal(err)
}
// A non-BDF sysfs entry must not influence peer discovery.
if err := os.WriteFile(filepath.Join(bridgeDir, "max_link_speed"), []byte("16.0 GT/s PCIe\n"), 0644); err != nil {
t.Fatal(err)
}
speed, width, ok := downstreamPCIeLinkCapabilityAt(bridgeDir)
if !ok || speed != "Gen3" || width != 8 {
t.Fatalf("downstream capability = (%q, %d, %v), want (Gen3, 8, true)", speed, width, ok)
}
}
func TestRenderPCIeLinkCheckSummaryDegradedGPU(t *testing.T) {
findings := []pcieLinkFinding{
{BDF: "0000:0d:00.0", Description: "NVIDIA GPU", IsGPU: true, GPUVendor: "nvidia",