From: netdev-bot+sashiko@kernel.org
To: mkl@pengutronix.de
Cc: netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org,
linux-can@vger.kernel.org, kernel@pengutronix.de,
hemanth.selam@gmail.com
Subject: Re: [PATCH net-next 30/37] can: hi311x: drop hi3110_lock before free_irq() on open failure
Date: Sat, 10 Oct 2026 14:03:06 +0000 [thread overview]
Message-ID: <179164098630.434549.4478960548038882608@kernel.org> (raw)
In-Reply-To: <20261009134323.64064-31-mkl@pengutronix.de>
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 0 · Medium: 1 (1) · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] The rollback in hi3110_open() (drivers/net/can/spi/hi311x.c,
lines 789-794) sets priv->force_quit = 1 and drops hi3110_lock before…
Pre-existing issues:
- [Medium] This problem wasn't introduced by this patch, but the driver's
own restart_work is never cancelled or flushed during shutdown.
--
can: hi311x: drop hi3110_lock before free_irq() on open failure
This patch changes the hi3110_open() error path. It now sets force_quit
and drops hi3110_lock before calling free_irq(), then takes the mutex
again for the remaining hardware cleanup. This avoids a deadlock against
the threaded IRQ handler, which takes hi3110_lock before it checks
force_quit.
Link: https://patch.msgid.link/20260820020631.316418-1-runyu.xiao@seu.edu.cn
> diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
> index 076a3efa1bfff..927555b5d581e 100644
> --- a/drivers/net/can/spi/hi311x.c
> +++ b/drivers/net/can/spi/hi311x.c
> @@ -787,7 +787,10 @@ static int hi3110_open(struct net_device *net)
> return 0;
>
> out_free_irq:
> + priv->force_quit = 1;
> + mutex_unlock(&priv->hi3110_lock);
> free_irq(spi->irq, priv);
[Severity: Medium]
Can this rollback turn the old deadlock into an IRQ storm when
hi3110_set_normal_mode() fails?
The IRQ is requested with IRQF_ONESHOT | IRQF_TRIGGER_HIGH. Before
hi3110_set_normal_mode() returns -EBUSY, it has already armed the chip:
drivers/net/can/spi/hi311x.c:hi3110_set_normal_mode() {
hi3110_write(spi, HI3110_WRITE_INTE, HI3110_INT_BUSERR |
HI3110_INT_RXFIFO | HI3110_INT_TXCPLT);
hi3110_write(spi, HI3110_WRITE_CTRL1, HI3110_CTRL1_TXEN);
...
hi3110_write(spi, HI3110_WRITE_CTRL0, reg);
mdelay(HI3110_OST_DELAY_MS);
reg = hi3110_read(spi, HI3110_READ_CTRL0);
if ((reg & HI3110_CTRL0_MODE_MASK) != reg)
return -EBUSY;
...
}
A received frame or a bus error during the mdelay() window can assert
INT. Once force_quit is set, hi3110_can_ist() skips the whole
while (!priv->force_quit) loop. It never reads STATF, the FIFO or INTF,
but it still returns IRQ_HANDLED.
irq_finalize_oneshot() then unmasks the line, which is still asserted.
The interrupt fires again right away, so the SCHED_FIFO IRQ thread spins
until free_irq() finally shuts the line down.
If the IRQ thread was blocked on hi3110_lock, the new mutex_unlock()
wakes it. On the same CPU (always the case on UP), it can preempt the
opener, which holds RTNL, before the opener reaches free_irq().
The opener then only runs again through RT throttling or the fair
dl_server. That bounds the stall to about one RT period by default, but
the stall can be indefinite if those safeguards are disabled.
Would it be better to quiet the chip while still holding the mutex,
before force_quit is set and the lock is dropped? That could mirror
what hi3110_stop() does:
hi3110_write(spi, HI3110_WRITE_CTRL1, 0x0);
hi3110_write(spi, HI3110_WRITE_INTE, 0x0);
hi3110_read(spi, HI3110_READ_INTF);
Another option is calling disable_irq_nosync() before mutex_unlock().
hi3110_stop() already uses the same force_quit then free_irq() ordering
while INTE is still enabled, so the same hazard exists there. In the
open() rollback path, though, it is new with this patch.
> + mutex_lock(&priv->hi3110_lock);
> hi3110_hw_sleep(spi);
> out_close:
> hi3110_power_enable(priv->transceiver, 0);
[Severity: Medium]
This is a pre-existing issue that this patch did not introduce, but is
priv->restart_work ever cancelled or flushed on shutdown?
hi3110_do_set_mode() queues it for CAN_MODE_START:
drivers/net/can/spi/hi311x.c:hi3110_do_set_mode() {
...
priv->restart_tx = 1;
if (priv->can.restart_ms == 0)
priv->after_suspend = HI3110_AFTER_SUSPEND_RESTART;
queue_work(priv->wq, &priv->restart_work);
...
}
hi3110_stop() calls close_candev(), which only cancels the CAN core's
delayed restart_work. It never calls
cancel_work_sync(&priv->restart_work), and neither does the hi3110_open()
rollback.
If the work is still pending at ifdown or during a failed open(),
hi3110_restart_work_handler() can run after cleanup. It takes
hi3110_lock and calls hi3110_hw_reset(), hi3110_setup() and
hi3110_set_normal_mode(), which re-arms INTE, TXEN and normal mode. It
then clears force_quit and calls netif_wake_queue() on the downed
interface.
The controller would then be back on the bus while the interface is
administratively down.
The new unlocked window around free_irq() in hi3110_open() gives the
worker one more place to run. It does not seem to make things worse than
the existing post-stop case, because free_irq() still completes and the
rollback then calls hi3110_hw_sleep().
There is no use-after-free here, because hi3110_can_remove() runs
destroy_workqueue() before free_candev().
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261009134323.64064-2-mkl%40pengutronix.de
next prev parent reply other threads:[~2026-10-10 14:03 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-09 13:27 [PATCH net-next 0/37] pull-request: can-next 2026-10-09 Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 01/37] can: dev: can_dropped_invalid_skb: drop CAN XL frames on non-CAN XL devices Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 02/37] can: raw: remove redundant NULL check before netdev_hold() Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 03/37] can: convert unreliable ARPHRD_CAN type checks to robust can_get_ml_priv() Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 04/37] can: proc: reset pkg_stats atomics individually Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 05/37] can: proc: remove pointers from CAN specific proc output Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 06/37] can: j1939: cancel pending address claim timers from j1939_ecu_unmap_all() Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 07/37] can: isotp: check the frame type, not just the length Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 08/37] dt-bindings: can: renesas,rcar-canfd: Document RZ/G3S SoC Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 09/37] can: rcar_canfd: Fix typos in macro names Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 10/37] can: skb: make echo skb freeing safe in any IRQ context Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 11/37] can: rcar_canfd: Allow the CAN FD clock to be sourced from fck Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 12/37] can: skb: make CAN skb allocation failure paths IRQ-safe Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 13/37] can: rcar_canfd: Do not set registers selecting the CAN mode Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 14/37] can: dev: can_put_echo_skb(): free skb on invalid echo index Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 15/37] can: rcar_canfd: Add support for Renesas RZ/G3S Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 16/37] dt-bindings: can: renesas,rcar-canfd: Document RZ/G3L SoC Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 17/37] can: rcar_canfd: Derive max_channels from the device tree Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 18/37] dt-bindings: net: can: convert grcan to DT schema Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 19/37] can: rcar_canfd: Add support for Renesas RZ/G3L Marc Kleine-Budde
2026-10-10 14:02 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 20/37] dt-bindings: can: renesas,rcar-canfd: Restrict resets in top-level Marc Kleine-Budde
2026-10-10 14:03 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 21/37] can: grcan: update the binding file reference in the driver comment Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 22/37] can: remove Softing CANcard driver Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 23/37] can: Convert to DEFINE_SIMPLE_DEV_PM_OPS() Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 24/37] can: cc770: don't discard the IRQ lookup error in probe Marc Kleine-Budde
2026-10-10 14:03 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 25/37] can: cc770: fix the clock divider check on the platform bus Marc Kleine-Budde
2026-10-09 13:27 ` [PATCH net-next 26/37] can: ems_usb: use usb_kill_urb() to stop the intr URB Marc Kleine-Budde
2026-10-10 14:03 ` netdev-bot+sashiko
2026-10-09 13:27 ` [PATCH net-next 27/37] can: esd: acc_start_xmit(): do not touch skb after can_put_echo_skb() Marc Kleine-Budde
2026-10-10 14:03 ` netdev-bot+sashiko
2026-10-09 13:28 ` [PATCH net-next 28/37] can: flexcan: flexcan_setup_stop_mode_gpr: fix OF node reference leak Marc Kleine-Budde
2026-10-09 13:28 ` [PATCH net-next 29/37] can: f81604: f81604_close(): fix use-after-free on disconnect Marc Kleine-Budde
2026-10-10 14:03 ` netdev-bot+sashiko
2026-10-09 13:28 ` [PATCH net-next 30/37] can: hi311x: drop hi3110_lock before free_irq() on open failure Marc Kleine-Budde
2026-10-10 14:03 ` netdev-bot+sashiko [this message]
2026-10-09 13:28 ` [PATCH net-next 31/37] can: kvaser_usb: refactor endpoint lookup Marc Kleine-Budde
2026-10-09 13:28 ` [PATCH net-next 32/37] can: kvaser_usb: validate command format before parsing in hydra receive path Marc Kleine-Budde
2026-10-09 13:28 ` [PATCH net-next 33/37] can: kvaser_pciefd: fix use-after-free in bec poll timer Marc Kleine-Budde
2026-10-09 13:28 ` [PATCH net-next 34/37] can: mcp251xfd: mcp251xfd_probe(): reject devices without match data Marc Kleine-Budde
2026-10-09 13:28 ` [PATCH net-next 35/37] can: sun4i_can: sun4ican_probe(): fix clk leak Marc Kleine-Budde
2026-10-10 14:03 ` netdev-bot+sashiko
2026-10-09 13:28 ` [PATCH net-next 36/37] can: ucan: fix repeated word 'is' in comment Marc Kleine-Budde
2026-10-09 13:28 ` [PATCH net-next 37/37] can: xilinx_can: set CAN FD flags on received frames Marc Kleine-Budde
2026-10-09 13:57 ` [PATCH net-next 0/37] pull-request: can-next 2026-10-09 Marc Kleine-Budde
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=179164098630.434549.4478960548038882608@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=davem@davemloft.net \
--cc=hemanth.selam@gmail.com \
--cc=kernel@pengutronix.de \
--cc=kuba@kernel.org \
--cc=linux-can@vger.kernel.org \
--cc=mkl@pengutronix.de \
--cc=netdev@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox