[Bug 166724] if_re(4): watchdog timeout
[email protected] Fri, 10 Jul 2026 12:56:05 +0000
| Newsgroups | gmane.os.freebsd.devel.net |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=166724 Jérémie Jourdin <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] --- Comment #134 from Jérémie Jourdin <[email protected]> --- Hi all, Same problem on 16.0-CURRENT with on-board Realtek RTL8168H NICs (re0: Chip rev. 0x54000000). Under sustained load these hit the long-standing re0: watchdog timeout. The usual advice is the net/realtek-re-kmod vendor driver, but we wanted to understand what in-tree re(4) is actually missing and, where we safely could, fix it in base rather than route around it. So we did a careful comparison of three drivers on the paths that matter here: in-tree if_re.c, Linux's r8169, and Realtek's own BSD-licensed vendor driver. That surfaced a handful of concrete, well-understood gaps. The attached patches close those, and only those. Every one of them does something that r8169 and/or the Realtek driver already do - none of it is speculative. What they address : 1. Lost transmit interrupts. re(4) already carries a 1 Hz "just in case" reclaim in re_tick(), with a comment admitting Tx-completion interrupts "seem to be lost on PCIe controllers." We close the two ways that actually happens: - A lost transmit doorbell (the "TxPoll requests are lost when packets are queued too close together" erratum). r8169 and the vendor driver both re-arm the transmitter from their completion routine; base only did so from the interrupt handlers. We move the re-arm into re_txeof() so every reclaim path — interrupt, the 1 Hz tick, and the watchdog — covers it. - A swallowed Tx-completion MSI. The INTx path already re-checks interrupt status before re-enabling interrupts; the MSI path did not. That asymmetry appears to be exactly why hw.re.msi_disable=1 has been a working workaround for so long. We make the MSI path re-check and flush, so a completion landing in the small window between ack and re-enable is serviced at once instead of waiting on the tick. 2. The reset / recovery path on 8168G and later. Base issues a STOPREQ command on these parts that neither r8169 nor Realtek's driver use on this family, and it frees the DMA buffers without first confirming the controller has stopped touching them. We follow the reference drivers: gate RXDV, drain the on-chip FIFOs, then reset the controller before the buffers are freed — so it can't DMA into memory that's about to be released. 3. Watchdog hardening + diagnostics. When the watchdog does fire, we (a) detect a controller that has dropped off the bus and stop trying to re-init it, (b) re-assert the ASPM disable — which r8169 flags as a common cause of these timeouts — and (c) enrich the existing watchdog log line with a one-line snapshot (interrupt mode, ISR/IMR, Tx-ring position) so a field occurrence tells us which failure class it was. No new log lines, no debug build needed. On the "conservative" side : - Every change lives in a teardown, error/recovery, or interrupt-tail path. The normal Tx/Rx fast path is untouched — throughput is unchanged (we measured gigabit line rate before and after). - They are register reads/writes only: no new locking, no allocations, no data-structure or KBI changes. Every added loop is bounded. - All are gated on hwrev / RL_FLAG_PCIE, so unaffected parts are never touched. - Compiles warning-free under the kernel's -Werror. We stopped short of porting the per-chip initialisation errata and MCU/PHY firmware that make up most of the divergence between base re(4) and the vendor driver. That is the high-risk surface, and it's the part we can't validate the way we can validate the defensive changes above — a wrong init-register write leaves the NIC down. The diagnostics in (3) exist precisely so that anyone can tell from the field whether the remaining stalls are the lost-interrupt/recovery class these patches address, or a genuine hardware-init stall that would justify that riskier work. This has been running on our RTL8168H build hosts, so far so good. The set is five small patches: - if_rlreg.h: MCU FIFO-status register definitions (8168G+) - re_stop(): 8168G+ quiesce (drop the spurious STOPREQ, drain FIFOs) + reset-before-free - re_txeof(): re-arm the Tx doorbell after reclaim - re_intr_msi(): recover a swallowed Tx-completion MSI + posted-write flush - re_watchdog(): dead-controller detection, ASPM re-assert, and the one-line diagnostics See the proposed re-pr166724.patch file attached. Hope this is useful and happy to iterate with reviewers, Jérémie -- You are receiving this mail because: You are on the CC list for the bug. You are the assignee for the bug.