lkml.org 
[lkml]   [2012]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 038/187] bnx2x: fix panic when TX ring is full
    Date
    From: Greg KH <gregkh@linuxfoundation.org>

    3.4-stable review patch. If anyone has any objections, please let me know.

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


    From: Eric Dumazet <edumazet@google.com>

    [ Upstream commit bc14786a100cc6a81cd060e8031ec481241b418c ]

    There is a off by one error in the minimal number of BD in
    bnx2x_start_xmit() and bnx2x_tx_int() before stopping/resuming tx queue.

    A full size GSO packet, with data included in skb->head really needs
    (MAX_SKB_FRAGS + 4) BDs, because of bnx2x_tx_split()

    This error triggers if BQL is disabled and heavy TCP transmit traffic
    occurs.

    bnx2x_tx_split() definitely can be called, remove a wrong comment.

    Reported-by: Tomas Hruby <thruby@google.com>
    Signed-off-by: Eric Dumazet <edumazet@google.com>
    Cc: Eilon Greenstein <eilong@broadcom.com>
    Cc: Yaniv Rosner <yanivr@broadcom.com>
    Cc: Merav Sicron <meravs@broadcom.com>
    Cc: Tom Herbert <therbert@google.com>
    Cc: Robert Evans <evansr@google.com>
    Cc: Willem de Bruijn <willemb@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 8 +++-----
    1 file changed, 3 insertions(+), 5 deletions(-)

    --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
    +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
    @@ -191,7 +191,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struc

    if ((netif_tx_queue_stopped(txq)) &&
    (bp->state == BNX2X_STATE_OPEN) &&
    - (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3))
    + (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4))
    netif_tx_wake_queue(txq);

    __netif_tx_unlock(txq);
    @@ -2349,8 +2349,6 @@ int bnx2x_poll(struct napi_struct *napi,
    /* we split the first BD into headers and data BDs
    * to ease the pain of our fellow microcode engineers
    * we use one mapping for both BDs
    - * So far this has only been observed to happen
    - * in Other Operating Systems(TM)
    */
    static noinline u16 bnx2x_tx_split(struct bnx2x *bp,
    struct bnx2x_fp_txdata *txdata,
    @@ -3002,7 +3000,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_b

    txdata->tx_bd_prod += nbd;

    - if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) {
    + if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) {
    netif_tx_stop_queue(txq);

    /* paired memory barrier is in bnx2x_tx_int(), we have to keep
    @@ -3011,7 +3009,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_b
    smp_mb();

    fp->eth_q_stats.driver_xoff++;
    - if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)
    + if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)
    netif_tx_wake_queue(txq);
    }
    txdata->tx_pkt++;



    \
     
     \ /
      Last update: 2012-07-13 02:41    [W:4.093 / U:0.428 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site