* [PATCH] can: mcp251xfd: Always stop on BUS_OFF and call netif_stop_queue [not found] <1b153bce-a66a-45ee-a5c6-963ea6fb1c82.949ef384-8293-46b8-903f-40a477c056ae.12523541-9b07-4081-b2ca-c8093468f69e@emailsignatures365.codetwo.com> @ 2026-11-09 7:06 ` Mike Looijmans 2026-11-10 20:27 ` netdev-bot+sashiko 0 siblings, 1 reply; 5+ messages in thread From: Mike Looijmans @ 2026-11-09 7:06 UTC (permalink / raw) To: linux-can Cc: Mike Looijmans, Manivannan Sadhasivam, Marc Kleine-Budde, Thomas Kopp, Vincent Mailhol, linux-kernel When there's an error attempting to store the BER counter, don't abort but continue shutting down the chip as required. After disabling communications, also stop the TX queue with a call to netif_stop_queue. When the interface restarts, mcp251xfd_set_mode will call netif_wake_queue and resume. This fixes a hangup in either send() or poll() from userspace. To reproduce: I ran "cansequence can0 -p" to flood the system with packets. While running that, I shorted the CAN signals, causing a bus error. Usually communications would resume after the CAN bus restarted, but sometimes the system got stuck and refused to send any more packets. The sending process would be in either poll() or send(), waiting for the queue to resume. To "unstuck" the process from send() it was sufficient to send any packet on the can interface from another process. To get it out of the poll() hang, only bringing the can interface down (and up) would work. After adding the netif_stop_queue call, I was unable to reproduce the problem. Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl> --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index f441f2265299e..9770416b24723 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1131,10 +1131,11 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) */ err = __mcp251xfd_get_berr_counter(priv->ndev, &priv->bec); if (err) - return err; + netdev_err(priv->ndev, "Failed to store BER counter\n"); mcp251xfd_chip_stop(priv, CAN_STATE_BUS_OFF); can_bus_off(priv->ndev); + netif_stop_queue(priv->ndev); } if (!skb) --- base-commit: 7475ea8b58616b33c04afb976cf0fbaad9dd63fb branch: linux-master-can-mcp251xfd-queue -- 2.43.0 Met vriendelijke groet / kind regards, Mike Looijmans System Expert TOPIC Embedded Products B.V. Materiaalweg 4, 5681 RJ Best The Netherlands T: +31 (0) 499 33 69 69 E: mike.looijmans@topic.nl W: www.topic.nl Please consider the environment before printing this e-mail ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] can: mcp251xfd: Always stop on BUS_OFF and call netif_stop_queue 2026-11-09 7:06 ` [PATCH] can: mcp251xfd: Always stop on BUS_OFF and call netif_stop_queue Mike Looijmans @ 2026-11-10 20:27 ` netdev-bot+sashiko 0 siblings, 0 replies; 5+ messages in thread From: netdev-bot+sashiko @ 2026-11-10 20:27 UTC (permalink / raw) To: mike.looijmans Cc: linux-can, mani, mkl, thomas.kopp, mailhol, linux-kernel, kuba Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider. Critical: 0 · High: 1 · Medium: 1 (1) · Low: 2 (2) 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). - [High] The new netif_stop_queue() in mcp251xfd_handle_cerrif() (line 1138) runs after the state that allows a restart has been published,… - [Medium] The new netif_stop_queue() is a lockless bit set from the threaded IRQ handler. - [Low] The patch fixes a hang that users can see: after bus-off, a sending process can block in send()/poll() until the interface is… - [Low] The commit message does not explain why the hang happens. Pre-existing issues: - [Medium] mcp251xfd_chip_stop() (lines 755-764) ignores errors from mcp251xfd_chip_interrupts_disable(), mcp251xfd_chip_rx_int_disable()… - [Low] If __mcp251xfd_get_berr_counter() fails in mcp251xfd_handle_cerrif(), priv->bec is not updated. - [Low] This problem wasn't introduced by this patch, but in mcp251xfd_handle_cerrif() the non-bus-off branch leaks the error skb. -- can: mcp251xfd: Always stop on BUS_OFF and call netif_stop_queue On bus-off, this patch keeps shutting the chip down even when the error counter read fails, and logs an error instead of returning early. It also stops the TX queue after can_bus_off() and relies on mcp251xfd_set_mode() to wake it on restart. The goal is to fix a send()/poll() hang seen after bus-off under heavy TX load. > This fixes a hangup in either send() or poll() from userspace. To > reproduce: I ran "cansequence can0 -p" to flood the system with packets. [Severity: Low] Should this have a Fixes: tag and Cc: stable? The bus-off block in mcp251xfd_handle_cerrif() goes back to the original driver submission. That includes the early return on a failed counter read and the missing queue stop. The only later change was the rename in eb79a267c9b3: Fixes: 55e5b97f003e ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN") > diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c > index f441f2265299e..9770416b24723 100644 > --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c > +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c > @@ -1131,10 +1131,11 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) > */ > err = __mcp251xfd_get_berr_counter(priv->ndev, &priv->bec); [Severity: Low] This isn't a bug introduced by this patch, but if __mcp251xfd_get_berr_counter() fails here, priv->bec is not updated. can_change_state() has already set priv->can.state to CAN_STATE_BUS_OFF. That means mcp251xfd_get_berr_counter() returns the stale copy to userspace: if (priv->can.state == CAN_STATE_BUS_OFF) { *bec = priv->bec; return 0; } The old return err path gave the same result. Could priv->bec be filled from the trec value already read at the top of mcp251xfd_handle_cerrif(), instead of doing a second TREC read? > if (err) > - return err; > + netdev_err(priv->ndev, "Failed to store BER counter\n"); [Severity: Low] Would it be useful to print err in this message? Before, the error went to the out_fail path in mcp251xfd_irq(), which printed the errno and called mcp251xfd_dump(). Now the error code is lost. The commit message doesn't say what this hunk fixes either. The old return err leaked the error skb allocated by mcp251xfd_alloc_can_err_skb(). It also left priv->can.state at CAN_STATE_BUS_OFF (set by can_change_state()), with the carrier still on and no restart scheduled. For the netif_stop_queue() part, the only justification given is: After adding the netif_stop_queue call, I was unable to reproduce the problem. Can the commit message explain the root cause? can_restart() assumes nothing is being transmitted during bus-off: /* No synchronization needed because the device is bus-off and * no messages can come in or go out. */ can_flush_echo_skb(dev); This driver broke that assumption by leaving the TX queue running. > > mcp251xfd_chip_stop(priv, CAN_STATE_BUS_OFF); [Severity: Medium] This is a pre-existing issue, but mcp251xfd_chip_stop() ignores errors from mcp251xfd_chip_interrupts_disable(), mcp251xfd_chip_rx_int_disable() and mcp251xfd_chip_set_mode(priv, MCP251XFD_REG_CON_MODE_CONFIG). With this patch it is now also called after a failed TREC read. Suppose the TREC read and the MODE_CONFIG write both fail briefly, and SPI recovers before the restart. Could the restart then reprogram the FIFOs while the chip is still in Normal mode, causing TEF consistency errors? The other callers of mcp251xfd_chip_stop() use the same unchecked, best-effort pattern. This only matters when both failures happen in that order. > can_bus_off(priv->ndev); > + netif_stop_queue(priv->ndev); [Severity: High] Can this netif_stop_queue() undo the wake from a restart that has already finished? By this point, mcp251xfd_chip_stop() has set CAN_STATE_BUS_OFF, and can_bus_off() has scheduled restart_work if restart_ms is set. When restart_ms is 0, a manual restart through can_restart_now() only needs priv->state == CAN_STATE_BUS_OFF. Neither restart path is serialized against the IRQ thread: restart path can_restart() mcp251xfd_set_mode() mcp251xfd_chip_start() /* state = CAN_STATE_ERROR_ACTIVE */ mcp251xfd_chip_interrupts_enable() netif_wake_queue(ndev); IRQ thread mcp251xfd_handle_cerrif() mcp251xfd_chip_stop(priv, CAN_STATE_BUS_OFF); can_bus_off(priv->ndev); netif_stop_queue(priv->ndev); /* runs after the wake */ If the wake happens first, the chip runs in ERROR_ACTIVE with an empty TX ring. mcp251xfd_handle_tefif() then never wakes the queue. A manual can_restart_now() also returns -EBUSY, because the state is no longer BUS_OFF. Wouldn't the queue then stay stopped until ifdown/ifup? That is the hang this patch is meant to fix. Would stopping the queue before mcp251xfd_chip_stop() and can_bus_off() avoid this? [Severity: Medium] Is this stop enough to keep the queue stopped during bus-off? Here, netif_stop_queue() is a lockless bit set from the threaded IRQ handler. It is not serialized against mcp251xfd_start_xmit(), and two other places can clear the bit without checking for bus-off. mcp251xfd_tx_busy() can restart the queue: netif_stop_queue(priv->ndev); /* Memory barrier before checking tx_free (head and tail) */ smp_mb(); if (mcp251xfd_get_tx_free(tx_ring) == 0) { ... return true; } netif_start_queue(priv->ndev); The IRQ loop handles TEF before CERRIF in the same pass. An xmit that saw the advanced tail and was then delayed can call netif_start_queue() after the bus-off stop. mcp251xfd_tx_failure_drop() also calls netif_wake_queue() unconditionally. It can be reached from a failing spi_async() in the xmit path, or from tx_work through mcp251xfd_tx_obj_write_sync(). tx_work is not cancelled on bus-off. Either way, the queue runs again while the chip is in CONFIG mode. That brings back the concurrency between can_put_echo_skb() and can_flush_echo_skb() in can_restart(). An xmit that has already passed the stopped check can also still write TX objects to the stopped chip. Would these windows close if netif_tx_disable() were called before mcp251xfd_chip_stop(), and the wake in mcp251xfd_tx_failure_drop() were made bus-off aware (or tx_work cancelled)? > } > > if (!skb) [Severity: Low] This isn't a bug introduced by this patch, but further down in mcp251xfd_handle_cerrif() the non-bus-off branch has a similar early return: if (new_state != CAN_STATE_BUS_OFF) { struct can_berr_counter bec; err = mcp251xfd_get_berr_counter(priv->ndev, &bec); if (err) return err; Does this return leak the skb from mcp251xfd_alloc_can_err_skb()? On this path the skb is neither freed nor queued to rx_offload. The IRQ handler then goes to out_fail, so at most one skb leaks per fatal SPI error. This code dates back to 55e5b97f003e. -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261109070605.9761-1-mike.looijmans%40topic.nl ^ permalink raw reply [flat|nested] 5+ messages in thread
[parent not found: <1b153bce-a66a-45ee-a5c6-963ea6fb1c82.949ef384-8293-46b8-903f-40a477c056ae.c7fafffb-93a7-4f4c-9c1e-df959c3ed3bb@emailsignatures365.codetwo.com>]
* [PATCH] can: mcp251xfd: Always stop on BUS_OFF and call netif_stop_queue [not found] <1b153bce-a66a-45ee-a5c6-963ea6fb1c82.949ef384-8293-46b8-903f-40a477c056ae.c7fafffb-93a7-4f4c-9c1e-df959c3ed3bb@emailsignatures365.codetwo.com> @ 2023-07-11 15:26 ` Mike Looijmans 2023-07-11 17:05 ` Marc Kleine-Budde 0 siblings, 1 reply; 5+ messages in thread From: Mike Looijmans @ 2023-07-11 15:26 UTC (permalink / raw) To: linux-can Cc: Mike Looijmans, David S. Miller, Eric Dumazet, Jakub Kicinski, Manivannan Sadhasivam, Marc Kleine-Budde, Paolo Abeni, Thomas Kopp, Wolfgang Grandegger, linux-kernel, netdev When there's an error attempting to store the BER counter, don't abort but continue shutting down the chip as required. After disabling communications, also stop the TX queue with a call to netif_stop_queue. When the interface restarts, mcp251xfd_set_mode will call netif_wake_queue and resume. This fixes a hangup in either send() or poll() from userspace. To reproduce: I ran "cansequence can0 -p" to flood the system with packets. While running that, I shorted the CAN signals, causing a bus error. Usually communications would resume after the CAN bus restarted, but sometimes the system got stuck and refused to send any more packets. The sending process would be in either poll() or send(), waiting for the queue to resume. To "unstuck" the process from send() it was sufficient to send any packet on the can interface from another process. To get it out of the poll() hang, only bringing the can interface down (and up) would work. After adding the netif_stop_queue call, I was unable to reproduce the problem. Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl> --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 68df6d4641b5..854e0644764c 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1084,10 +1084,11 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) */ err = __mcp251xfd_get_berr_counter(priv->ndev, &priv->bec); if (err) - return err; + netdev_err(priv->ndev, "Failed to store BER counter\n"); mcp251xfd_chip_stop(priv, CAN_STATE_BUS_OFF); can_bus_off(priv->ndev); + netif_stop_queue(priv->ndev); } if (!skb) -- 2.17.1 Met vriendelijke groet / kind regards, Mike Looijmans System Expert TOPIC Embedded Products B.V. Materiaalweg 4, 5681 RJ Best The Netherlands T: +31 (0) 499 33 69 69 E: mike.looijmans@topicproducts.com W: www.topic.nl Please consider the environment before printing this e-mail ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] can: mcp251xfd: Always stop on BUS_OFF and call netif_stop_queue 2023-07-11 15:26 ` Mike Looijmans @ 2023-07-11 17:05 ` Marc Kleine-Budde 2023-07-12 5:43 ` Mike Looijmans 0 siblings, 1 reply; 5+ messages in thread From: Marc Kleine-Budde @ 2023-07-11 17:05 UTC (permalink / raw) To: Mike Looijmans Cc: linux-can, David S. Miller, Eric Dumazet, Jakub Kicinski, Manivannan Sadhasivam, Paolo Abeni, Thomas Kopp, Wolfgang Grandegger, linux-kernel, netdev [-- Attachment #1: Type: text/plain, Size: 2420 bytes --] On 11.07.2023 17:26:47, Mike Looijmans wrote: > When there's an error attempting to store the BER counter, don't abort > but continue shutting down the chip as required. If you refer to an error by __mcp251xfd_get_berr_counter(), it's not a store error, but a failure of regmap_read(priv->map_reg, MCP251XFD_REG_TREC, &trec). By default the SPI transfers are CRC enabled and no/wrong data from the chip will be detected and return an error here (after 3 retires). In out of memory conditions or other kernel errors might be possible here, too. Have you seen a problem here? But as we shut down the chip here anyways, we can ignore the error here. > After disabling communications, also stop the TX queue with a call to > netif_stop_queue. can_bus_off() will call netif_carrier_off(), isn't this sufficient? Have you enabled automatic restart in case of bus off? I think the netdev watchdog will kick you, if the interface has a stooped queue for too long (IIRC 5 seconds). > When the interface restarts, mcp251xfd_set_mode will > call netif_wake_queue and resume. > > This fixes a hangup in either send() or poll() from userspace. To > reproduce: I ran "cansequence can0 -p" to flood the system with packets. > While running that, I shorted the CAN signals, causing a bus error. > Usually communications would resume after the CAN bus restarted, but > sometimes the system got stuck and refused to send any more packets. > The sending process would be in either poll() or send(), waiting for > the queue to resume. To "unstuck" the process from send() it was > sufficient to send any packet on the can interface from another > process. To get it out of the poll() hang, only bringing the can > interface down (and up) would work. > > After adding the netif_stop_queue call, I was unable to reproduce the > problem. The newly added netif_stop_queue() will cause the netif_wake_queue() in the mcp251xfd_set_mode() to actually wake the queue. If you observe a problem, I think it's a general problem, so all drivers would be effected. > Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl> Marc -- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung Nürnberg | Phone: +49-5121-206917-129 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 | [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] can: mcp251xfd: Always stop on BUS_OFF and call netif_stop_queue 2023-07-11 17:05 ` Marc Kleine-Budde @ 2023-07-12 5:43 ` Mike Looijmans 0 siblings, 0 replies; 5+ messages in thread From: Mike Looijmans @ 2023-07-12 5:43 UTC (permalink / raw) To: Marc Kleine-Budde Cc: linux-can, David S. Miller, Eric Dumazet, Jakub Kicinski, Manivannan Sadhasivam, Paolo Abeni, Thomas Kopp, Wolfgang Grandegger, linux-kernel, netdev Met vriendelijke groet / kind regards, Mike Looijmans System Expert TOPIC Embedded Products B.V. Materiaalweg 4, 5681 RJ Best The Netherlands T: +31 (0) 499 33 69 69 E: mike.looijmans@topicproducts.com W: www.topic.nl Please consider the environment before printing this e-mail On 11-07-2023 19:05, Marc Kleine-Budde wrote: > On 11.07.2023 17:26:47, Mike Looijmans wrote: >> When there's an error attempting to store the BER counter, don't abort >> but continue shutting down the chip as required. > > If you refer to an error by __mcp251xfd_get_berr_counter(), it's not a > store error, but a failure of regmap_read(priv->map_reg, > MCP251XFD_REG_TREC, &trec). By default the SPI transfers are CRC enabled > and no/wrong data from the chip will be detected and return an error > here (after 3 retires). In out of memory conditions or other kernel > errors might be possible here, too. > > Have you seen a problem here? But as we shut down the chip here anyways, > we can ignore the error here. Excactly my point, the important task here is to report the bus off state. I haven't seen the error trigger, so it wasn't the cause of our problems. In retrospect, maybe I should have split this in two patches? >> After disabling communications, also stop the TX queue with a call to >> netif_stop_queue. > > can_bus_off() will call netif_carrier_off(), isn't this sufficient? Have > you enabled automatic restart in case of bus off? I think the netdev > watchdog will kick you, if the interface has a stooped queue for too > long (IIRC 5 seconds). Apparently not. The problem also occurred in the field, where the CAN communication got stuck for something like a full day. Automatic restart was enabled, with a 100ms timeout. Setting a shorter timeout like 50 ms seemed to make the problem more likely to occur What I also noticed, but didn't accurately measure, is that the time it took to recover used to be somewhat random, it could take up to about a second for packets to start going out again, as observed by watching LEDs. After adding netif_stop_queue the recovery was almost instantaneous. > >> When the interface restarts, mcp251xfd_set_mode will >> call netif_wake_queue and resume. >> >> This fixes a hangup in either send() or poll() from userspace. To >> reproduce: I ran "cansequence can0 -p" to flood the system with packets. >> While running that, I shorted the CAN signals, causing a bus error. >> Usually communications would resume after the CAN bus restarted, but >> sometimes the system got stuck and refused to send any more packets. >> The sending process would be in either poll() or send(), waiting for >> the queue to resume. To "unstuck" the process from send() it was >> sufficient to send any packet on the can interface from another >> process. To get it out of the poll() hang, only bringing the can >> interface down (and up) would work. >> >> After adding the netif_stop_queue call, I was unable to reproduce the >> problem. > > The newly added netif_stop_queue() will cause the netif_wake_queue() in > the mcp251xfd_set_mode() to actually wake the queue. If you observe a > problem, I think it's a general problem, so all drivers would be > effected. After two days digging, my conclusion was that "something" wasn't getting a proper "kick" when the CAN interface came back online. One could argue the netif_stop_queue should be put into can_bus_off. But the netif_wake_queue call is in the driver, so that would break symmetry. > >> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl> > > Marc > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-10 20:27 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <1b153bce-a66a-45ee-a5c6-963ea6fb1c82.949ef384-8293-46b8-903f-40a477c056ae.12523541-9b07-4081-b2ca-c8093468f69e@emailsignatures365.codetwo.com>
2026-11-09 7:06 ` [PATCH] can: mcp251xfd: Always stop on BUS_OFF and call netif_stop_queue Mike Looijmans
2026-11-10 20:27 ` netdev-bot+sashiko
[not found] <1b153bce-a66a-45ee-a5c6-963ea6fb1c82.949ef384-8293-46b8-903f-40a477c056ae.c7fafffb-93a7-4f4c-9c1e-df959c3ed3bb@emailsignatures365.codetwo.com>
2023-07-11 15:26 ` Mike Looijmans
2023-07-11 17:05 ` Marc Kleine-Budde
2023-07-12 5:43 ` Mike Looijmans
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®