Drive a noise cable on the i40e pair, cycling its link down and up since the module PHYs ignore everything softer, and flag its absence beside the error columns
This commit is contained in:
@@ -252,6 +252,7 @@ var intervalCols = []colSpec{
|
||||
{group: "NOW", title: "corrupt", width: 7, right: true},
|
||||
{group: "NOW", title: "link", width: 7, right: true},
|
||||
{group: "NOW", title: "internal", width: 8, right: true},
|
||||
{group: "NOW", title: "noise", width: 7, right: true},
|
||||
{group: "OVERALL", title: "elapsed", width: 9, right: true},
|
||||
{group: "OVERALL", title: "packets", width: 9, right: true},
|
||||
{group: "OVERALL", title: "bytes", width: 9, right: true},
|
||||
@@ -340,9 +341,10 @@ func (d *direction) displayView() view {
|
||||
return v
|
||||
}
|
||||
|
||||
// The same figures the panel draws, in the same order: the last second as rates
|
||||
// and error flags, then everything since the reset.
|
||||
func totalRow(elapsed time.Duration, v view, target float64, length string) []string {
|
||||
// The same figures the panel draws, in the same order: the last second as
|
||||
// rates and error flags with the noise cable riding at the end of them, then
|
||||
// everything since the reset.
|
||||
func totalRow(elapsed time.Duration, v view, target float64, length string, noiseMissing uint64) []string {
|
||||
return []string{
|
||||
rateCell(v.rxGbps*1e9, target*1e9),
|
||||
scaleSI(v.rxPPS),
|
||||
@@ -350,6 +352,7 @@ func totalRow(elapsed time.Duration, v view, target float64, length string) []st
|
||||
flagCell(v.window.corrupt),
|
||||
flagCell(v.window.link),
|
||||
flagCell(v.window.internal),
|
||||
flagCell(noiseMissing),
|
||||
scaleTime(elapsed),
|
||||
scaleCount(v.rxFrames),
|
||||
scaleCount(v.rxBytes),
|
||||
@@ -513,6 +516,8 @@ const (
|
||||
|
||||
probeEther uint16 = etherBase + numStreams
|
||||
|
||||
testDriver = "ice"
|
||||
|
||||
// A constant rather than the negotiated speed, since this has to come up
|
||||
// with no cable in the port and nothing to negotiate.
|
||||
linkSpeed = 10.0
|
||||
@@ -523,10 +528,11 @@ const (
|
||||
var frameSizes = []int{60, 128, 256, 512, 1024, 1280, 1514}
|
||||
|
||||
func main() {
|
||||
// The names the kernel gives the only two ports built into it, since as
|
||||
// PID 1 there is no udev to rename them and no command line to pass.
|
||||
aName := flag.String("a", "eth0", "first interface")
|
||||
bName := flag.String("b", "eth1", "second interface")
|
||||
// Left empty, the test pair is found by driver name instead: as PID 1 there
|
||||
// is no udev to pin names and no command line to pass, and which port gets
|
||||
// which ethN shifts with every driver built into the kernel.
|
||||
aName := flag.String("a", "", "first interface (default: the ice pair)")
|
||||
bName := flag.String("b", "", "second interface")
|
||||
nsPerM := flag.Float64("ns-per-m", 4.85, "mean of both directions, per metre of cable")
|
||||
flag.Parse()
|
||||
|
||||
@@ -580,6 +586,13 @@ func run(aName, bName string, nsPerM float64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if aName == "" || bName == "" {
|
||||
var err error
|
||||
aName, bName, err = driverPair(testDriver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
a, err := lookupEndpoint(aName)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -588,6 +601,11 @@ func run(aName, bName string, nsPerM float64) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
noise, err := newNoiser()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer noise.close()
|
||||
for _, e := range []endpoint{a, b} {
|
||||
for _, s := range frameSizes {
|
||||
if s > e.mtu+ethHdrLen {
|
||||
@@ -596,7 +614,8 @@ func run(aName, bName string, nsPerM float64) error {
|
||||
}
|
||||
}
|
||||
|
||||
a.tag, b.tag = "A", "B"
|
||||
a.tag, b.tag = "TEST A", "TEST B"
|
||||
noise.eps[0].tag, noise.eps[1].tag = "NOISE A", "NOISE B"
|
||||
ifnames := []string{a.name, b.name}
|
||||
|
||||
ethertypes := make([]uint16, numStreams)
|
||||
@@ -604,7 +623,8 @@ func run(aName, bName string, nsPerM float64) error {
|
||||
ethertypes[i] = uint16(etherBase + i)
|
||||
}
|
||||
|
||||
if err := reportChecks("HOST SETTINGS", configureSystem(ifnames, ethertypes)); err != nil {
|
||||
if err := reportChecks("HOST SETTINGS",
|
||||
append(configureSystem(ifnames, ethertypes), configureNoise(noise.names())...)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -623,7 +643,7 @@ func run(aName, bName string, nsPerM float64) error {
|
||||
}()
|
||||
|
||||
var linkRows [][]string
|
||||
for _, e := range []endpoint{a, b} {
|
||||
for _, e := range []endpoint{a, b, noise.eps[0], noise.eps[1]} {
|
||||
linkRows = append(linkRows, []string{
|
||||
paint(e.tag, cCyan), e.name, e.macString(), fmt.Sprintf("%d", e.mtu),
|
||||
})
|
||||
@@ -652,6 +672,13 @@ func run(aName, bName string, nsPerM float64) error {
|
||||
defer wg.Done()
|
||||
samp.run(&done, startTx)
|
||||
}()
|
||||
// Not gated on startTx: the cycle and the connected verdict are wanted the
|
||||
// moment the panel is, and nothing it does touches the measurement.
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
noise.run(&done)
|
||||
}()
|
||||
// Every return from here on stops the workers before the deferred closes
|
||||
// pull their sockets out from under them: otherwise the sampler panics on a
|
||||
// closed fd and can mask the error that actually ended the run. An error
|
||||
@@ -719,7 +746,8 @@ func run(aName, bName string, nsPerM float64) error {
|
||||
if m, ok := cableMetres(views, nsPerM); ok {
|
||||
cable = fmt.Sprintf("%.1f", m)
|
||||
}
|
||||
if err := disp.render(totalView(views), now.Sub(start), cable); err != nil {
|
||||
if err := disp.render(totalView(views), now.Sub(start), cable,
|
||||
noise.missing()); err != nil {
|
||||
return err
|
||||
}
|
||||
case now := <-tick.C:
|
||||
@@ -733,7 +761,8 @@ func run(aName, bName string, nsPerM float64) error {
|
||||
if m, ok := cableMetres(rows, nsPerM); ok {
|
||||
length = fmt.Sprintf("%.1f", m)
|
||||
}
|
||||
for _, line := range stats.emit(totalRow(elapsed, totalView(rows), target, length)) {
|
||||
for _, line := range stats.emit(totalRow(elapsed, totalView(rows), target, length,
|
||||
noise.missing())) {
|
||||
fmt.Println(line)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user