[PATCH net v2 0/3] can: fix bus-off restart during device close

Cunhao Lu 1579567540 at qq.com
Tue Oct 13 22:06:54 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>

pw-bot: cr


More information about the Linux-rockchip mailing list