From 1c7d6584a7811b7785ae5c1e378f14b5ba0971cf Mon Sep 17 00:00:00 2001 From: takeshi_hoshina Date: Mon, 2 Nov 2020 11:07:33 +0900 Subject: basesystem-jj recipes --- ...canfd-fix-one-more-interrupt-storm-window.patch | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0469-rcar_canfd-fix-one-more-interrupt-storm-window.patch (limited to 'bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0469-rcar_canfd-fix-one-more-interrupt-storm-window.patch') diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0469-rcar_canfd-fix-one-more-interrupt-storm-window.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0469-rcar_canfd-fix-one-more-interrupt-storm-window.patch new file mode 100644 index 00000000..506ff276 --- /dev/null +++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0469-rcar_canfd-fix-one-more-interrupt-storm-window.patch @@ -0,0 +1,67 @@ +From bfdc3bf828002a0550b8183a67879fc3a9246795 Mon Sep 17 00:00:00 2001 +From: Nikita Yushchenko +Date: Thu, 6 Feb 2020 23:13:19 +0300 +Subject: [PATCH] rcar_canfd: fix one more interrupt storm window + +When more than one rcar_canfd channel works simultaneously, same irq and +same irq handler, rcar_canfd_global_interrupt(), is shared between them +all. Entry into this handler while Rx interrupt for one channel is masked +per NAPI, becomes a very frequent event. + +Code makes an attempt to alter interrupt mask only when NAPI suggests to +do so. However that code is racy, and with frequent call to handler with +masked interrupt, this race actually happens. + +The race window is: +- after code in napi_complete_done() clears NAPIF_STATE_SCHED flag inside + NAPI state, but before napi_complete_done() returns true, side-called + interrupt handler detects pending (although masked) Rx, calls + napi_schedule_prep(), and NAPIF_STATE_SCHED flag is re-set, +- then napi_complete_done() returns true and Rx interrupt gets unmasked, +- then unmasked interrupt fires, but this time NAPIF_STATE_SCHED flag + is already set, so napi_schedule_prep() returns false, +- which causes return from interrupt handler without touching interrupt, + and IRQ storm is entered. + +To fix it, active Rx interrupt must be UNCONDITIONALLY masked inside the +handler. Failing to mask active interrupt immediately results into IRQ +storm, regardless of NAPI state or whatever other conditions. + +Once napi_schedule_prep() is called after this unconditional masking, future +call to NAPI poller and evential interrupt unmask is guaranteed. + +Signed-off-by: Nikita Yushchenko +--- + drivers/net/can/rcar/rcar_canfd.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c +index 0017ab9..056a5f6 100644 +--- a/drivers/net/can/rcar/rcar_canfd.c ++++ b/drivers/net/can/rcar/rcar_canfd.c +@@ -1101,13 +1101,16 @@ static irqreturn_t rcar_canfd_global_interrupt(int irq, void *dev_id) + /* Handle Rx interrupts */ + sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(ridx)); + if (likely(sts & RCANFD_RFSTS_RFIF)) { +- if (napi_schedule_prep(&priv->napi)) { +- /* Disable Rx FIFO interrupts */ +- rcar_canfd_clear_bit(priv->base, +- RCANFD_RFCC(ridx), +- RCANFD_RFCC_RFIE); ++ /* If Rx FIFO interrupt is there, it must be masked ++ * UNCONDITIONALLY, otherwise IRQ storm will start */ ++ rcar_canfd_clear_bit(priv->base, ++ RCANFD_RFCC(ridx), ++ RCANFD_RFCC_RFIE); ++ /* The above calls ensure that napi polling will be ++ * called sometime AFTER the above call, which ++ * eventually ensures interrupt re-enable */ ++ if (napi_schedule_prep(&priv->napi)) + __napi_schedule(&priv->napi); +- } + } + } + return IRQ_HANDLED; +-- +2.7.4 + -- cgit 1.2.3-korg