The following happend on an i.MX25 using flexcan with many packets on the bus: The rx-offload queue reached a length more than skb_queue_len_max. So in can_rx_offload_offload_one() the drop variable was set to true which made the call to .mailbox_read() (here: flexcan_mailbox_read()) just return ERR_PTR(-ENOBUFS) (plus some irrelevant hardware interaction) and so can_rx_offload_offload_one() returned ERR_PTR(-ENOBUFS), too. Now can_rx_offload_irq_offload_fifo() looks as follows: while (1) { skb = can_rx_offload_offload_one(offload, 0); if (IS_ERR(skb)) continue; ... } As the i.MX25 is a single core CPU while the rx-offload processing is active there is no thread to process packets from the offload queue and so it doesn't get shorter. The result is a tight loop: can_rx_offload_offload_one() does nothing relevant and returns an error code and so can_rx_offload_irq_offload_fifo() calls can_rx_offload_offload_one() again. To break that loop don't continue calling can_rx_offload_offload_one() after it reported an error. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx> --- Hello, this patch just implements the obvious change to break the loop. I'm not 100% certain that there is no corner case where the break is wrong. The problem exists at least since v5.6, didn't go back further to check. This fixes a hard hang on said i.MX25. Best regards Uwe drivers/net/can/dev/rx-offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/dev/rx-offload.c b/drivers/net/can/dev/rx-offload.c index a32a01c172d4..d5d33692bb6a 100644 --- a/drivers/net/can/dev/rx-offload.c +++ b/drivers/net/can/dev/rx-offload.c @@ -207,7 +207,7 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload) while (1) { skb = can_rx_offload_offload_one(offload, 0); if (IS_ERR(skb)) - continue; + break; if (!skb) break; -- 2.36.1