diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2021-05-10 22:51:39 +0200 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2021-07-25 11:36:25 +0200 |
commit | 30bfec4fec5902731c8823f51c5332e6f2b2312a (patch) | |
tree | f20de65159e6972b74d74b1f323305ada814ce66 /include/linux/can | |
parent | 1e0d8e507ea42dd37f52636db300de7ea7118012 (diff) | |
download | linux-30bfec4fec5902731c8823f51c5332e6f2b2312a.tar.gz linux-30bfec4fec5902731c8823f51c5332e6f2b2312a.tar.bz2 linux-30bfec4fec5902731c8823f51c5332e6f2b2312a.zip |
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 'include/linux/can')
-rw-r--r-- | include/linux/can/rx-offload.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/can/rx-offload.h b/include/linux/can/rx-offload.h index 516f64df0ebc..c11477620403 100644 --- a/include/linux/can/rx-offload.h +++ b/include/linux/can/rx-offload.h @@ -50,6 +50,7 @@ unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, int can_rx_offload_queue_tail(struct can_rx_offload *offload, struct sk_buff *skb); void can_rx_offload_irq_finish(struct can_rx_offload *offload); +void can_rx_offload_threaded_irq_finish(struct can_rx_offload *offload); void can_rx_offload_del(struct can_rx_offload *offload); void can_rx_offload_enable(struct can_rx_offload *offload); |