lkml.org 
[lkml]   [2018]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.15 075/105] can: peak/pcie_fd: fix echo_skb is occupied! bug
    Date
    4.15-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Stephane Grosjean <s.grosjean@peak-system.com>

    commit e6048a00cfd0863d32f53b226e0b9a3633fc3332 upstream.

    This patch makes atomic the handling of the linux-can echo_skb array and
    the network tx queue. This prevents from the "BUG! echo_skb is occupied!"
    message to be printed by the linux-can core, in SMP environments.

    Reported-by: Diana Burgess <diana@peloton-tech.com>
    Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
    Cc: linux-stable <stable@vger.kernel.org>
    Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/net/can/peak_canfd/peak_canfd.c | 12 ++++++------
    drivers/net/can/peak_canfd/peak_pciefd_main.c | 8 ++++++--
    2 files changed, 12 insertions(+), 8 deletions(-)

    --- a/drivers/net/can/peak_canfd/peak_canfd.c
    +++ b/drivers/net/can/peak_canfd/peak_canfd.c
    @@ -262,7 +262,6 @@ static int pucan_handle_can_rx(struct pe

    spin_lock_irqsave(&priv->echo_lock, flags);
    can_get_echo_skb(priv->ndev, msg->client);
    - spin_unlock_irqrestore(&priv->echo_lock, flags);

    /* count bytes of the echo instead of skb */
    stats->tx_bytes += cf_len;
    @@ -271,6 +270,7 @@ static int pucan_handle_can_rx(struct pe
    /* restart tx queue (a slot is free) */
    netif_wake_queue(priv->ndev);

    + spin_unlock_irqrestore(&priv->echo_lock, flags);
    return 0;
    }

    @@ -726,11 +726,6 @@ static netdev_tx_t peak_canfd_start_xmit
    */
    should_stop_tx_queue = !!(priv->can.echo_skb[priv->echo_idx]);

    - spin_unlock_irqrestore(&priv->echo_lock, flags);
    -
    - /* write the skb on the interface */
    - priv->write_tx_msg(priv, msg);
    -
    /* stop network tx queue if not enough room to save one more msg too */
    if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
    should_stop_tx_queue |= (room_left <
    @@ -742,6 +737,11 @@ static netdev_tx_t peak_canfd_start_xmit
    if (should_stop_tx_queue)
    netif_stop_queue(ndev);

    + spin_unlock_irqrestore(&priv->echo_lock, flags);
    +
    + /* write the skb on the interface */
    + priv->write_tx_msg(priv, msg);
    +
    return NETDEV_TX_OK;
    }

    --- a/drivers/net/can/peak_canfd/peak_pciefd_main.c
    +++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c
    @@ -349,8 +349,12 @@ static irqreturn_t pciefd_irq_handler(in
    priv->tx_pages_free++;
    spin_unlock_irqrestore(&priv->tx_lock, flags);

    - /* wake producer up */
    - netif_wake_queue(priv->ucan.ndev);
    + /* wake producer up (only if enough room in echo_skb array) */
    + spin_lock_irqsave(&priv->ucan.echo_lock, flags);
    + if (!priv->ucan.can.echo_skb[priv->ucan.echo_idx])
    + netif_wake_queue(priv->ucan.ndev);
    +
    + spin_unlock_irqrestore(&priv->ucan.echo_lock, flags);
    }

    /* re-enable Rx DMA transfer for this CAN */

    \
     
     \ /
      Last update: 2018-03-27 18:48    [W:4.049 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site