镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

WIP macb stall patches - #7667

Draft
nbuchwitz wants to merge 5 commits into
raspberrypi:rpi-6.18.yfrom
nbuchwitz:devel/macb-stall
Draft

nbuchwitz wants to merge 5 commits into
raspberrypi:rpi-6.18.yfrom
nbuchwitz:devel/macb-stall

Conversation

@nbuchwitz

Copy link
Copy Markdown
Contributor

Some patches to try with #7661

@nbuchwitz

Copy link
Copy Markdown
Contributor Author

@pelwell, can you please trigger the builds? Thanks

When the frames went out but their TCOMP interrupt got lost, TBQP
already matches tx_head and macb_tx_restart() does nothing. TX NAPI
never runs again and the queue stays stopped for good.

Fixes: e438ec3 ("net: macb: add TX stall timeout callback to recover from lost TSTART write")
Link: raspberrypi#7661
[nb: open-code macb_queue_isr_clear(), not available in 6.18]

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
The frames dropped on a TX error are never returned to BQL. Each error
shrinks the BQL budget for good until the queue stops with an empty
ring.

netdev_tx_reset_queue() is not safe here as the task runs without
tx_ptr_lock, so macb_start_xmit() may still be queueing.

Fixes: e6a5321 ("net: cadence: macb: Implement BQL")
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
@nbuchwitz

Copy link
Copy Markdown
Contributor Author

@pelwell can you please re-trigger the build? Thanks!

The IER write at the end of macb_tx_poll() is posted, so the ring
check right after it can run before TCOMP is unmasked. A frame that
completes in that window never raises an interrupt. With TSO this
happens when TXUBR triggers a poll while the frame is still on the
wire. BQL keeps the queue stopped on that frame and only the watchdog
gets it going again.

Read IMR back after the write so the check runs with TCOMP unmasked.
macb_rx_poll() has the same window.

Fixes: 138badb ("net: macb: use NAPI for TX completion path")
Fixes: 0bf476f ("net: macb: Fix lost RX packet wakeup race in NAPI receive")
Link: raspberrypi#7661
Link: https://lore.kernel.org/netdev/20260514215459.36109-3-lukasz@raczylo.com/
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
chrta-wmi and others added 2 commits October 23, 2026 11:59
gem_shuffle_tx_one_ring() rotates the software TX ring so that the
tail sits at index 0 and resets queue->tx_tail to 0, but it never
reprograms the hardware transmit buffer queue pointer (TBQP). Other
paths that reset tx_tail to the ring base (macb_init_buffers() and
macb_tx_error_task()) also reprogram TBQP to queue->tx_ring_dma; this
path does not, leaving TBQP pointing at a stale descriptor.

gem_shuffle_tx_rings() runs on every link-up from
macb_mac_link_up(). After a few link up/down flaps that leave
un-completed descriptors in the ring, the stale TBQP keeps pointing at
a descriptor whose used bit is set. When TX is re-enabled on link-up,
the GEM reads that used descriptor and raises TXUBR. macb_interrupt()
schedules the TX NAPI, macb_tx_poll() makes no progress (work_done ==
0) and macb_tx_restart() re-issues TSTART, which makes the controller
read the same used descriptor again and re-assert TXUBR. As the MAC
interrupt is level-triggered, it never deasserts and one CPU is pegged
at 100% in the threaded handler, eventually triggering "sched: RT
throttling activated" and a dead network interface.

Fix it by reprogramming TBQP to the ring base on every path of
gem_shuffle_tx_one_ring() that resets tx_tail to 0, mirroring
macb_tx_error_task(). The early return for an already-aligned tail is
left untouched as TBQP is already consistent there. This is safe
because the shuffle runs from macb_mac_link_up() while TE is still
disabled, so the transmitter is halted.

Fixes: 881a026 ("net: macb: Shuffle the tx ring before enabling tx")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Link: https://lore.kernel.org/netdev/20261022-std-macb-v14-send-v1-2-9187bc545bf6@beckhoff.com/
Signed-off-by: Christian Taedcke <christian.taedcke@weidmueller.com>
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Write TSTART in macb_mac_link_up() for every queue that still has
frames outstanding once transmit has been re-enabled.

Frames queued before a link-down stay in the ring, and setting NCR.TE
does not start the transmitter; the driver relies on the next
macb_start_xmit() to write TSTART. If BQL stopped the queue before the
link went down, that transmit never comes and the queue stays idle
until the netdev watchdog fires.

Like the rotation, the kick is skipped on the at91rm9200 EMAC, which
uses its own TX path.

Fixes: 881a026 ("net: macb: Shuffle the tx ring before enabling tx")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/netdev/20261022-std-macb-v14-send-v1-5-9187bc545bf6@beckhoff.com/
Assisted-by: LLM
Signed-off-by: Steffen Dirkwinkel <s.dirkwinkel@beckhoff.com>
[nb: taken without the rotation rework it sits on, the kick goes right after TE is set]
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants