lkml.org 
[lkml]   [2022]   [Sep]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 056/141] can: flexcan: flexcan_mailbox_read() fix return value for drop = true
    Date
    From: Marc Kleine-Budde <mkl@pengutronix.de>

    commit a09721dd47c8468b3f2fdd73f40422699ffe26dd upstream.

    The following happened on an i.MX25 using flexcan with many packets on
    the bus:

    The rx-offload queue reached a length more than skb_queue_len_max. In
    can_rx_offload_offload_one() the drop variable was set to true which
    made the call to .mailbox_read() (here: flexcan_mailbox_read()) to
    _always_ return ERR_PTR(-ENOBUFS) and drop the rx'ed CAN frame. So
    can_rx_offload_offload_one() returned ERR_PTR(-ENOBUFS), too.

    can_rx_offload_irq_offload_fifo() looks as follows:

    | while (1) {
    | skb = can_rx_offload_offload_one(offload, 0);
    | if (IS_ERR(skb))
    | continue;
    | if (!skb)
    | break;
    | ...
    | }

    The flexcan driver wrongly always returns ERR_PTR(-ENOBUFS) if drop is
    requested, even if there is no CAN frame pending. As the i.MX25 is a
    single core CPU, while the rx-offload processing is active, there is
    no thread to process packets from the offload queue. So the queue
    doesn't get any shorter and this results is a tight loop.

    Instead of always returning ERR_PTR(-ENOBUFS) if drop is requested,
    return NULL if no CAN frame is pending.

    Changes since v1: https://lore.kernel.org/all/20220810144536.389237-1-u.kleine-koenig@pengutronix.de
    - don't break in can_rx_offload_irq_offload_fifo() in case of an error,
    return NULL in flexcan_mailbox_read() in case of no pending CAN frame
    instead

    Fixes: 4e9c9484b085 ("can: rx-offload: Prepare for CAN FD support")
    Link: https://lore.kernel.org/all/20220811094254.1864367-1-mkl@pengutronix.de
    Cc: stable@vger.kernel.org # v5.5
    Suggested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
    Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
    Tested-by: Thorsten Scherer <t.scherer@eckelmann.de>
    Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/can/flexcan.c | 10 +++++-----
    1 file changed, 5 insertions(+), 5 deletions(-)

    --- a/drivers/net/can/flexcan.c
    +++ b/drivers/net/can/flexcan.c
    @@ -954,11 +954,6 @@ static struct sk_buff *flexcan_mailbox_r
    u32 reg_ctrl, reg_id, reg_iflag1;
    int i;

    - if (unlikely(drop)) {
    - skb = ERR_PTR(-ENOBUFS);
    - goto mark_as_read;
    - }
    -
    mb = flexcan_get_mb(priv, n);

    if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
    @@ -987,6 +982,11 @@ static struct sk_buff *flexcan_mailbox_r
    reg_ctrl = priv->read(&mb->can_ctrl);
    }

    + if (unlikely(drop)) {
    + skb = ERR_PTR(-ENOBUFS);
    + goto mark_as_read;
    + }
    +
    if (reg_ctrl & FLEXCAN_MB_CNT_EDL)
    skb = alloc_canfd_skb(offload->dev, &cfd);
    else

    \
     
     \ /
      Last update: 2022-09-26 13:05    [W:4.276 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site