Message ID | 20221031090420.589386-1-biju.das.jz@bp.renesas.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | can: rcar_canfd: rcar_canfd_handle_global_receive(): fix IRQ storm on global FIFO receive | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Series ignored based on subject |
On Mon, Oct 31, 2022 at 09:04:20AM +0000, Biju Das wrote: > commit 702de2c21eed04c67cefaaedc248ef16e5f6b293 upstream. > > We are seeing an IRQ storm on the global receive IRQ line under heavy > CAN bus load conditions with both CAN channels enabled. > > Conditions: > > The global receive IRQ line is shared between can0 and can1, either of > the channels can trigger interrupt while the other channel's IRQ line > is disabled (RFIE). > > When global a receive IRQ interrupt occurs, we mask the interrupt in > the IRQ handler. Clearing and unmasking of the interrupt is happening > in rx_poll(). There is a race condition where rx_poll() unmasks the > interrupt, but the next IRQ handler does not mask the IRQ due to > NAPIF_STATE_MISSED flag (e.g.: can0 RX FIFO interrupt is disabled and > can1 is triggering RX interrupt, the delay in rx_poll() processing > results in setting NAPIF_STATE_MISSED flag) leading to an IRQ storm. > > This patch fixes the issue by checking IRQ active and enabled before > handling the IRQ on a particular channel. > > Fixes: dd3bd23eb438 ("can: rcar_canfd: Add Renesas R-Car CAN FD driver") > Suggested-by: Marc Kleine-Budde <mkl@pengutronix.de> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> > Link: https://lore.kernel.org/all/20221025155657.1426948-2-biju.das.jz@bp.renesas.com > Cc: stable@vger.kernel.org # 4.9.x > [mkl: adjust commit message] > Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> > [biju: removed gpriv from RCANFD_RFCC_RFIE macro] > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> > --- > Resending to 4.9 with confilcts[1] fixed > [1] https://lore.kernel.org/stable/OS0PR01MB59226F2443DFCE7C5D73778786379@OS0PR01MB5922.jpnprd01.prod.outlook.com/T/#t > --- > drivers/net/can/rcar/rcar_canfd.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) All now queued up, thanks. greg k-h
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index a127c853a4e9..694a3354554f 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -1079,7 +1079,7 @@ static irqreturn_t rcar_canfd_global_interrupt(int irq, void *dev_id) struct rcar_canfd_global *gpriv = dev_id; struct net_device *ndev; struct rcar_canfd_channel *priv; - u32 sts, gerfl; + u32 sts, cc, gerfl; u32 ch, ridx; /* Global error interrupts still indicate a condition specific @@ -1097,7 +1097,9 @@ 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)) { + cc = rcar_canfd_read(priv->base, RCANFD_RFCC(ridx)); + if (likely(sts & RCANFD_RFSTS_RFIF && + cc & RCANFD_RFCC_RFIE)) { if (napi_schedule_prep(&priv->napi)) { /* Disable Rx FIFO interrupts */ rcar_canfd_clear_bit(priv->base,