Date: Sun, 19 Jul 2026 18:50:49 +0000 From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: =?utf-8?Q?J=C3=A9r=C3=A9mie?= Jourdin <jeremie@jourdin.org> Subject: git: 4bff6b9f5cef - main - re(4): re-arm the Tx doorbell when re_txeof() leaves a non-empty ring Message-ID: <6a5d1c89.3e1f4.2470105a@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=4bff6b9f5cef13df8540fa6869bd6707f8e7575d commit 4bff6b9f5cef13df8540fa6869bd6707f8e7575d Author: Jérémie Jourdin <jeremie@jourdin.org> AuthorDate: 2026-07-19 18:42:22 +0000 Commit: Adrian Chadd <adrian@FreeBSD.org> CommitDate: 2026-07-19 18:45:15 +0000 re(4): re-arm the Tx doorbell when re_txeof() leaves a non-empty ring On PCIe parts a TxPoll request can be lost when packets are queued in quick succession, leaving owned descriptors with no transfer in progress until the watchdog fires. re_txeof() runs from the interrupt handlers, re_tick() and re_watchdog(), so re-writing TXSTART whenever the ring is still non-empty turns a potential 5-second stall into at most one tick. One register write on a path that already took an interrupt; fast path untouched. * Sustained bidirectional load on RTL8168H; no Tx stalls, no throughput regression at 941 Mbps line rate. Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D58277 PR: kern/166724 --- sys/dev/re/if_re.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index cf7ba90c9a5a..4df75474bce3 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -2464,6 +2464,17 @@ re_txeof(struct rl_softc *sc) /* No changes made to the TX ring, so no flush needed */ if (sc->rl_ldata.rl_tx_free != sc->rl_ldata.rl_tx_desc_cnt) { + /* + * Some descriptors are still owned by the controller. On PCIe + * parts a TxPoll request can be lost when Tx packets are queued + * too close together, leaving a non-empty ring with no transfer + * in progress. Re-arm the transmitter here -- this routine is + * reached from the interrupt handlers, re_tick() and + * re_watchdog() -- so a lost poll cannot stall the ring until + * the watchdog fires. + */ + if ((sc->rl_flags & RL_FLAG_PCIE) != 0) + CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START); #ifdef RE_TX_MODERATION /* * If not all descriptors have been reaped yet, reloadhome | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a5d1c89.3e1f4.2470105a>
