can: grcan: only use the NAPI poll budget for RX
BugLink: https://bugs.launchpad.net/bugs/1980399
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: 6cec9b07fe
("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>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
This commit is contained in:
parent
73ed8373f0
commit
9008617164
|
@ -1137,7 +1137,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;
|
||||
|
@ -1145,7 +1145,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))
|
||||
|
@ -1159,8 +1159,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)
|
||||
|
@ -1242,19 +1240,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 receiveing 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
|
||||
|
@ -1271,7 +1263,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,
|
||||
|
|
Loading…
Reference in New Issue