lkml.org 
[lkml]   [2022]   [May]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 036/135] can: grcan: only use the NAPI poll budget for RX
    Date
    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
    @@ -1137,7 +1137,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;
    @@ -1145,7 +1145,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))
    @@ -1159,8 +1159,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)
    @@ -1242,19 +1240,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
    @@ -1271,7 +1263,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,

    \
     
     \ /
      Last update: 2022-05-10 16:00    [W:4.268 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site