lkml.org 
[lkml]   [2012]   [Jun]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 70/82] r8169: fix unsigned int wraparound with TSO
    3.2-stable review patch.  If anyone has any objections, please let me know.

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

    From: Julien Ducourthial <jducourt@free.fr>

    [ Upstream commit 477206a018f902895bfcd069dd820bfe94c187b1 ]

    The r8169 may get stuck or show bad behaviour after activating TSO :
    the net_device is not stopped when it has no more TX descriptors.
    This problem comes from TX_BUFS_AVAIL which may reach -1 when all
    transmit descriptors are in use. The patch simply tries to keep positive
    values.

    Tested with 8111d(onboard) on a D510MO, and with 8111e(onboard) on a
    Zotac 890GXITX.

    Signed-off-by: Julien Ducourthial <jducourt@free.fr>
    Acked-by: Francois Romieu <romieu@fr.zoreil.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/net/ethernet/realtek/r8169.c | 16 ++++++++++------
    1 file changed, 10 insertions(+), 6 deletions(-)

    diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
    index 5f3fa32..cc2565c 100644
    --- a/drivers/net/ethernet/realtek/r8169.c
    +++ b/drivers/net/ethernet/realtek/r8169.c
    @@ -62,8 +62,12 @@
    #define R8169_MSG_DEFAULT \
    (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)

    -#define TX_BUFFS_AVAIL(tp) \
    - (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
    +#define TX_SLOTS_AVAIL(tp) \
    + (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx)
    +
    +/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */
    +#define TX_FRAGS_READY_FOR(tp,nr_frags) \
    + (TX_SLOTS_AVAIL(tp) >= (nr_frags + 1))

    /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
    The RTL chips use a 64 element hash table based on the Ethernet CRC. */
    @@ -5512,7 +5516,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
    u32 opts[2];
    int frags;

    - if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
    + if (unlikely(!TX_FRAGS_READY_FOR(tp, skb_shinfo(skb)->nr_frags))) {
    netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n");
    goto err_stop_0;
    }
    @@ -5560,7 +5564,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,

    RTL_W8(TxPoll, NPQ);

    - if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
    + if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
    /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
    * not miss a ring update when it notices a stopped queue.
    */
    @@ -5574,7 +5578,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
    * can't.
    */
    smp_mb();
    - if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)
    + if (TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS))
    netif_wake_queue(dev);
    }

    @@ -5683,7 +5687,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
    */
    smp_mb();
    if (netif_queue_stopped(dev) &&
    - (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) {
    + TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
    netif_wake_queue(dev);
    }
    /*



    \
     
     \ /
      Last update: 2012-06-08 08:02    [W:2.811 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site