]> git.baikalelectronics.ru Git - kernel.git/commitdiff
can: grcan: only use the NAPI poll budget for RX
authorAndreas Larsson <andreas@gaisler.com>
Fri, 29 Apr 2022 08:46:56 +0000 (10:46 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Fri, 29 Apr 2022 10:09:32 +0000 (12:09 +0200)
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: c7e7f7ef6626 ("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>
drivers/net/can/grcan.c

index 4ca3da56d3aa57c958dc3a694c9b49bb060f0566..5215bd9b2c80d04bcdbcfd98d9b9aad164eb932f 100644 (file)
@@ -1125,7 +1125,7 @@ static int grcan_close(struct net_device *dev)
        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(struct net_device *dev, int budget)
 
        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(struct net_device *dev, int budget)
        }
 
        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 *napi, int budget)
        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 *napi, int budget)
                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,