From: sashiko-bot@kernel.org
To: "Cunhao Lu" <1579567540@qq.com>
Cc: linux-can@vger.kernel.org,
"Marc Kleine-Budde" <mkl@pengutronix.de>,
"Oliver Hartkopp" <socketcan@hartkopp.net>,
"Vincent Mailhol" <mailhol@kernel.org>,
"Oleksij Rempel" <o.rempel@pengutronix.de>
Subject: Re: [PATCH net v6 3/6] can: rockchip_canfd: cancel bus-off restart before closing the device
Date: Sun, 18 Oct 2026 14:51:04 +0000 [thread overview]
Message-ID: <sashiko-outbox-176216@kernel.org> (raw)
In-Reply-To: <20261017-rockchip-canfd-restart-close-v6-3-ed605feb4b6e@qq.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] can: rockchip_canfd: ad-hoc flag synchronization in rkcanfd_set_mode()
--
commit 84108d981e4356f8149159f043033d7bbecd5e53
Author: Cunhao Lu <1579567540@qq.com>
can: rockchip_canfd: cancel bus-off restart before closing the device
This commit cancels bus-off restart work at the beginning of ndo_stop(),
synchronizes interrupt and timestamp handling across controller restart in
rkcanfd_set_mode(), and disables RX offload on request_irq() failure in
rkcanfd_open().
> diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
> index 37c1c22c40c9f..4b3db07242395 100644
> --- a/drivers/net/can/rockchip/rockchip_canfd-core.c
> +++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
[ ... ]
> @@ -356,7 +357,18 @@ static int rkcanfd_set_mode(struct net_device *ndev,
>
> switch (mode) {
> case CAN_MODE_START:
> + rkcanfd_chip_interrupts_disable(priv);
> + /* Flush the interrupt mask write before suspending the handler. */
> + rkcanfd_read(priv, RKCANFD_REG_INT_MASK);
> + /* Keep shared IRQs from accessing the device during restart. */
> + WRITE_ONCE(priv->irq_suspended, true);
> + /* Wait for handlers that already passed the suspended check. */
> + synchronize_irq(ndev->irq);
> + rkcanfd_timestamp_stop_sync(priv);
> +
> rkcanfd_chip_start(priv);
> + /* Publish the initialized state before resuming IRQ handling. */
> + smp_store_release(&priv->irq_suspended, false);
> rkcanfd_chip_interrupts_enable(priv);
> netif_wake_queue(ndev);
> break;
> @@ -666,6 +678,10 @@ static irqreturn_t rkcanfd_irq(int irq, void *dev_id)
> struct rkcanfd_priv *priv = dev_id;
> u32 reg_int_unmasked, reg_int;
>
> + /* Pairs with the release after restart has initialized the device. */
> + if (smp_load_acquire(&priv->irq_suspended))
> + return IRQ_NONE;
> +
> reg_int_unmasked = rkcanfd_read(priv, RKCANFD_REG_INT);
> reg_int = reg_int_unmasked & ~priv->reg_int_mask_default;
[Severity: Medium]
Does using priv->irq_suspended as a boolean gate flag between
rkcanfd_set_mode() and rkcanfd_irq() leave a race window during controller
restart and shared IRQ handling?
Setting priv->irq_suspended on entry to rkcanfd_set_mode() and clearing it on
exit acts as an ad-hoc lock that is invisible to lockdep and does not
serialize against other concurrent readers or writers of shared state (such as
rkcanfd_get_berr_counter()).
In addition, rkcanfd_chip_start() already puts the controller into
RKCANFD_REG_MODE_WORK_MODE and sets priv->can.state = CAN_STATE_ERROR_ACTIVE
before rkcanfd_set_mode() clears priv->irq_suspended:
can_restart()
rkcanfd_set_mode(ndev, CAN_MODE_START)
rkcanfd_chip_start(priv)
rkcanfd_chip_set_work_mode(priv);
priv->can.state = CAN_STATE_ERROR_ACTIVE;
smp_store_release(&priv->irq_suspended, false);
rkcanfd_chip_interrupts_enable(priv);
netif_wake_queue(ndev);
Because rkcanfd_irq() reads the raw unmasked interrupt status from
RKCANFD_REG_INT and masks it in software with ~priv->reg_int_mask_default
rather than consulting RKCANFD_REG_INT_MASK, a shared IRQ firing on the
IRQF_SHARED line after smp_store_release(&priv->irq_suspended, false) (or an
interrupt firing right as rkcanfd_chip_interrupts_enable() unmasks hardware
interrupts) can enter rkcanfd_irq() and handle a new bus-off condition before
rkcanfd_set_mode() finishes:
rkcanfd_irq()
rkcanfd_handle_state_error_int()
rkcanfd_chip_stop(priv, CAN_STATE_BUS_OFF)
can_bus_off(ndev)
When rkcanfd_set_mode() then executes rkcanfd_chip_interrupts_enable(priv) and
netif_wake_queue(ndev), wouldn't it unmask interrupts on the stopped
controller and wake the transmit queue while priv->can.state is
CAN_STATE_BUS_OFF?
Similarly, because rkcanfd_irq() only checks priv->irq_suspended (which is
only set during rkcanfd_set_mode()) and masks RKCANFD_REG_INT with
~priv->reg_int_mask_default, shared IRQs arriving during rkcanfd_open()
between request_irq() and rkcanfd_chip_interrupts_enable(), or while in
CAN_STATE_BUS_OFF after rkcanfd_chip_stop() masks RKCANFD_REG_INT_MASK, can
still evaluate pending bits in RKCANFD_REG_INT. Would a proper spinlock (or
honoring the active mask state under a lock) avoid this race?
[ ... ]
> diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
> index 95bea9bfd8a2f..e1debab54534e 100644
> --- a/drivers/net/can/rockchip/rockchip_canfd.h
> +++ b/drivers/net/can/rockchip/rockchip_canfd.h
> @@ -480,6 +480,7 @@ struct rkcanfd_priv {
>
> u32 reg_mode_default;
> u32 reg_int_mask_default;
> + bool irq_suspended;
> struct rkcanfd_devtype_data devtype_data;
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261017-rockchip-canfd-restart-close-v6-0-ed605feb4b6e@qq.com?part=3
next prev parent reply other threads:[~2026-10-18 14:51 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 14:50 [PATCH net v6 0/6] can: fix bus-off restart and device close races Cunhao Lu via B4 Relay
2026-10-17 14:50 ` Cunhao Lu
2026-10-17 14:50 ` Cunhao Lu via B4 Relay
2026-10-17 14:50 ` [PATCH net v6 1/6] can: dev: prevent bus-off recovery when the interface is not running Cunhao Lu via B4 Relay
2026-10-17 14:50 ` Cunhao Lu
2026-10-17 14:50 ` Cunhao Lu via B4 Relay
2026-10-17 14:50 ` [PATCH net v6 2/6] can: dev: add close_candev_cancel_restart_sync() Cunhao Lu via B4 Relay
2026-10-17 14:50 ` Cunhao Lu
2026-10-17 14:50 ` Cunhao Lu via B4 Relay
2026-10-17 14:50 ` [PATCH net v6 3/6] can: rockchip_canfd: cancel bus-off restart before closing the device Cunhao Lu via B4 Relay
2026-10-17 14:50 ` Cunhao Lu
2026-10-17 14:50 ` Cunhao Lu via B4 Relay
2026-10-18 14:51 ` sashiko-bot [this message]
2026-10-18 15:12 ` Cunhao Lu
2026-10-17 14:50 ` [PATCH net v6 4/6] can: rockchip_canfd: prevent timestamp work from rearming after bus-off Cunhao Lu via B4 Relay
2026-10-17 14:50 ` Cunhao Lu
2026-10-17 14:50 ` Cunhao Lu via B4 Relay
2026-10-17 14:50 ` [PATCH net v6 5/6] can: rockchip_canfd: serialize TX with bus-off and restart Cunhao Lu via B4 Relay
2026-10-17 14:50 ` Cunhao Lu
2026-10-17 14:50 ` Cunhao Lu via B4 Relay
2026-10-17 14:50 ` [PATCH net v6 6/6] can: rockchip_canfd: serialize timecounter timestamp conversion Cunhao Lu via B4 Relay
2026-10-17 14:50 ` Cunhao Lu
2026-10-17 14:50 ` Cunhao Lu via B4 Relay
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-176216@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=1579567540@qq.com \
--cc=linux-can@vger.kernel.org \
--cc=mailhol@kernel.org \
--cc=mkl@pengutronix.de \
--cc=o.rempel@pengutronix.de \
--cc=sashiko-reviews@lists.linux.dev \
--cc=socketcan@hartkopp.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.