[PATCH net v2 0/3] can: fix bus-off restart during device close
Cunhao Lu
1579567540 at qq.com
Tue Oct 13 19:54:21 PDT 2026
This work started from a real failure on a production robot using a
LubanCat-5IO with an RK3588. RX continued, but the TX queue remained
stopped and subsequent sends returned ENOBUFS. The interface still
reported ERROR-ACTIVE, and the hardware indicated neither a bus-off
condition nor a pending TX request.
While testing the echo-loss fix with fault injection, I discovered a
separate race between bus-off restart and device close. This series fixes
that race; the fix for the original TX stall will follow separately.
When automatic bus-off recovery is enabled, bringing the interface down
can race with a pending or running restart. The Rockchip driver currently
relies on close_candev() to cancel restart_work, but calls it only after
freeing the IRQ, disabling RX offload, and stopping the controller. A
restart in that interval can re-enable the controller and its interrupts
after IRQ teardown, and requeue timestamp work after it has been stopped.
That work can subsequently access registers after runtime suspend
disables the controller clocks.
The networking core clears the running flag before calling ndo_stop().
The first patch uses that flag to avoid scheduling or starting bus-off
recovery once the interface is observed to be no longer running. The
second patch adds close_candev_cancel_restart_sync() so drivers can wait
for recovery separately from the echo cleanup in close_candev(). The
third patch uses this helper at the start of the Rockchip close path.
The running-state checks do not replace synchronization with a restart
that has already passed the check. Rockchip waits for that work before
tearing down its resources, and keeps close_candev() at the end for the
final cancellation and echo cleanup. IRQ exclusion during hardware
reinitialization is retained; the shared IRQ is not disabled while the
close path waits for restart work.
I tested v2 on a LubanCat-5IO running a PREEMPT_RT kernel, using the same
setup and procedure as v1. The 1 Mbit/s CAN bus was connected to four
CANopen motors operating at 100 Hz and four sensors operating at 20 Hz.
A bitrate mismatch forced bus-off with automatic restart set to 100 ms.
The v2 campaign completed 380 valid bus-off iterations, covering automatic
recovery, close while recovery was pending, close near three delay points,
200 randomized stress iterations, manual recovery, and reopen after close.
All 380 iterations reached bus-off and scheduled recovery.
---
Changes in v2:
- Split the series into the common checks, the cancellation helper, and
its use in Rockchip.
- Check netif_running() after the do_set_mode capability check and before
the restart notification, echo cleanup, and carrier update.
- Only queue automatic recovery for a running interface; keep reporting
bus-off and make the log message match the scheduling decision.
- Add close_candev_cancel_restart_sync() in linux/can/dev.h and use it in
close_candev() without changing the existing cleanup order.
- Replace the Rockchip mutex and closing flag with an early call to the
helper. Drop the extra close-path IRQ synchronization and mask readback.
- Retain IRQ exclusion around hardware reinitialization in the restart
callback.
- Link to v1:
https://lore.kernel.org/linux-can/tencent_5802EE88434010229EDF7A53084D994C6106@qq.com/
To: Marc Kleine-Budde <mkl at pengutronix.de>
To: Vincent Mailhol <mailhol at kernel.org>
To: Heiko Stuebner <heiko at sntech.de>
To: "David S. Miller" <davem at davemloft.net>
To: Wolfgang Grandegger <wg at grandegger.com>
To: Oliver Hartkopp <socketcan at hartkopp.net>
To: kernel at pengutronix.de
Cc: linux-can at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-rockchip at lists.infradead.org
---
Cunhao Lu (3):
can: dev: prevent bus-off recovery when the interface is not running
can: dev: add close_candev_cancel_restart_sync()
can: rockchip_canfd: cancel bus-off restart before closing the device
drivers/net/can/dev/dev.c | 12 +++++++-----
drivers/net/can/rockchip/rockchip_canfd-core.c | 3 +++
include/linux/can/dev.h | 12 ++++++++++++
3 files changed, 22 insertions(+), 5 deletions(-)
---
base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
change-id: 20261013-rockchip-canfd-restart-close-ebde5954f1bf
Best regards,
--
Cunhao Lu <1579567540 at qq.com>
More information about the linux-arm-kernel
mailing list