summaryrefslogtreecommitdiff
path: root/drivers/net/can/spi
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2021-05-10 22:51:39 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2021-07-25 11:36:25 +0200
commit30bfec4fec5902731c8823f51c5332e6f2b2312a (patch)
treef20de65159e6972b74d74b1f323305ada814ce66 /drivers/net/can/spi
parent1e0d8e507ea42dd37f52636db300de7ea7118012 (diff)
can: rx-offload: can_rx_offload_threaded_irq_finish(): add new function to be called from threaded interrupt
After reading all CAN frames from the controller in the IRQ handler and storing them into a skb_queue, the driver calls napi_schedule(). In the napi poll function the skb from the skb_queue are then pushed into the networking stack. However if napi_schedule() is called from a threaded IRQ handler this triggers the following error: | NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!! To avoid this, create a new rx-offload function (can_rx_offload_threaded_irq_finish()) with a call to local_bh_disable()/local_bh_enable() around the napi_schedule() call. Convert all drivers that call can_rx_offload_irq_finish() from threaded IRQ context to can_rx_offload_threaded_irq_finish(). Link: https://lore.kernel.org/r/20210724204745.736053-4-mkl@pengutronix.de Suggested-by: Daniel Glöckner <dg@emlix.com> Tested-by: Oleksij Rempel <o.rempel@pengutronix.de> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can/spi')
-rw-r--r--drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
index f3b267ec22e0..6962ab2749df 100644
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -2196,7 +2196,7 @@ static irqreturn_t mcp251xfd_irq(int irq, void *dev_id)
priv->regs_status.intf);
if (!(intf_pending)) {
- can_rx_offload_irq_finish(&priv->offload);
+ can_rx_offload_threaded_irq_finish(&priv->offload);
return handled;
}
@@ -2298,7 +2298,7 @@ static irqreturn_t mcp251xfd_irq(int irq, void *dev_id)
} while (1);
out_fail:
- can_rx_offload_irq_finish(&priv->offload);
+ can_rx_offload_threaded_irq_finish(&priv->offload);
netdev_err(priv->ndev, "IRQ handler returned %d (intf=0x%08x).\n",
err, priv->regs_status.intf);