| From 2873d4d52f7c52d60b316ba6c47bd7122b5a9861 Mon Sep 17 00:00:00 2001 |
| From: Andreas Larsson <andreas@gaisler.com> |
| Date: Fri, 29 Apr 2022 10:46:56 +0200 |
| Subject: can: grcan: only use the NAPI poll budget for RX |
| |
| From: Andreas Larsson <andreas@gaisler.com> |
| |
| commit 2873d4d52f7c52d60b316ba6c47bd7122b5a9861 upstream. |
| |
| The previous split budget between TX and RX made it return not using |
| the entire budget but at the same time not having calling called |
| napi_complete. This sometimes led to the poll to not be called, and at |
| the same time having TX and RX interrupts disabled resulting in the |
| driver getting stuck. |
| |
| Fixes: 6cec9b07fe6a ("can: grcan: Add device driver for GRCAN and GRHCAN cores") |
| Link: https://lore.kernel.org/all/20220429084656.29788-4-andreas@gaisler.com |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Andreas Larsson <andreas@gaisler.com> |
| Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/can/grcan.c | 22 +++++++--------------- |
| 1 file changed, 7 insertions(+), 15 deletions(-) |
| |
| --- a/drivers/net/can/grcan.c |
| +++ b/drivers/net/can/grcan.c |
| @@ -1125,7 +1125,7 @@ static int grcan_close(struct net_device |
| return 0; |
| } |
| |
| -static int grcan_transmit_catch_up(struct net_device *dev, int budget) |
| +static void grcan_transmit_catch_up(struct net_device *dev) |
| { |
| struct grcan_priv *priv = netdev_priv(dev); |
| unsigned long flags; |
| @@ -1133,7 +1133,7 @@ static int grcan_transmit_catch_up(struc |
| |
| spin_lock_irqsave(&priv->lock, flags); |
| |
| - work_done = catch_up_echo_skb(dev, budget, true); |
| + work_done = catch_up_echo_skb(dev, -1, true); |
| if (work_done) { |
| if (!priv->resetting && !priv->closing && |
| !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) |
| @@ -1147,8 +1147,6 @@ static int grcan_transmit_catch_up(struc |
| } |
| |
| spin_unlock_irqrestore(&priv->lock, flags); |
| - |
| - return work_done; |
| } |
| |
| static int grcan_receive(struct net_device *dev, int budget) |
| @@ -1230,19 +1228,13 @@ static int grcan_poll(struct napi_struct |
| struct net_device *dev = priv->dev; |
| struct grcan_registers __iomem *regs = priv->regs; |
| unsigned long flags; |
| - int tx_work_done, rx_work_done; |
| - int rx_budget = budget / 2; |
| - int tx_budget = budget - rx_budget; |
| + int work_done; |
| |
| - /* Half of the budget for receiving messages */ |
| - rx_work_done = grcan_receive(dev, rx_budget); |
| + work_done = grcan_receive(dev, budget); |
| |
| - /* Half of the budget for transmitting messages as that can trigger echo |
| - * frames being received |
| - */ |
| - tx_work_done = grcan_transmit_catch_up(dev, tx_budget); |
| + grcan_transmit_catch_up(dev); |
| |
| - if (rx_work_done < rx_budget && tx_work_done < tx_budget) { |
| + if (work_done < budget) { |
| napi_complete(napi); |
| |
| /* Guarantee no interference with a running reset that otherwise |
| @@ -1259,7 +1251,7 @@ static int grcan_poll(struct napi_struct |
| spin_unlock_irqrestore(&priv->lock, flags); |
| } |
| |
| - return rx_work_done + tx_work_done; |
| + return work_done; |
| } |
| |
| /* Work tx bug by waiting while for the risky situation to clear. If that fails, |