diff --git a/main.go b/main.go index a91cf42..b9239bb 100644 --- a/main.go +++ b/main.go @@ -197,7 +197,7 @@ type sample struct { lost, late uint64 crcErr, badMagic uint64 badLen uint64 - txErrs, txShort uint64 + txErrs uint64 rxErrs uint64 } @@ -246,7 +246,6 @@ func (d *direction) snapshot() sample { s.txFrames += t.frames.Load() s.txBytes += t.bytes.Load() s.txErrs += t.errs.Load() - s.txShort += t.short.Load() } for _, r := range d.rxStats { s.rxFrames += r.frames.Load() @@ -331,16 +330,14 @@ func errsBetween(b, n counterSet) errs { // checksum, a header that is not ours, and a length that cannot be. corrupt: (n.s.crcErr - b.s.crcErr) + (n.s.badMagic - b.s.badMagic) + (n.s.badLen - b.s.badLen), - // A frame the stack refused and a frame the driver dropped are the same - // failure seen from either side of the ring, and never the same frame - // twice: a send that fails never reaches the driver to be dropped. - link: (n.nic - b.nic) + (n.s.txErrs - b.s.txErrs) + (n.s.rxErrs - b.s.rxErrs), - // Ours rather than the cable's: frames the kernel threw away because we - // did not drain the ring fast enough, and frames so far out of order - // that our own bookkeeping had already written them off. The second is - // unreachable while each stream has a flow rule to its own queue, which - // is exactly why it is worth counting: it fires if that stops holding. - internal: (n.drops - b.drops) + (n.s.late - b.s.late), + // What the hardware reported. Nothing the host declined to send is here, + // so this one going red means the cable. + link: (n.nic - b.nic) + (n.s.rxErrs - b.s.rxErrs), + // Ours rather than the cable's. A late frame is unreachable while each + // stream has a flow rule to its own queue, which is exactly why it is + // worth counting. + internal: (n.drops - b.drops) + (n.s.late - b.s.late) + + (n.s.txErrs - b.s.txErrs), } } diff --git a/tx.go b/tx.go index e2d6b8e..beb281f 100644 --- a/tx.go +++ b/tx.go @@ -10,8 +10,7 @@ type txStats struct { frames atomic.Uint64 bytes atomic.Uint64 errs atomic.Uint64 - short atomic.Uint64 - _ [32]byte + _ [40]byte } type txWorker struct { @@ -62,13 +61,10 @@ func (w *txWorker) run(done *atomic.Bool) { w.stats.bytes.Add(b) seq += uint64(n) } - if n < w.batch { - switch { - case n < 0 && err != unix.EINTR && err != unix.EAGAIN && err != unix.ENOBUFS: - w.stats.errs.Add(1) - default: - w.stats.short.Add(1) - } + // Taking fewer of the vector than offered is the ring's room, not a frame + // lost: the rest go on the next pass. + if n < 0 && err != unix.EINTR && err != unix.EAGAIN && err != unix.ENOBUFS { + w.stats.errs.Add(1) } } }