netdev
[Top] [All Lists]

[PATCH net-drivers-2.4 3/10] e1000: Avoid race between e1000_watchdog an

To: "jgarzik@xxxxxxxxx" <jgarzik@xxxxxxxxx>
Subject: [PATCH net-drivers-2.4 3/10] e1000: Avoid race between e1000_watchdog and e1000_clean_tx_irq
From: Malli Chilakala <mallikarjuna.chilakala@xxxxxxxxx>
Date: Tue, 15 Feb 2005 13:33:22 -0800 (PST)
Cc: netdev <netdev@xxxxxxxxxxx>
Replyto: "Malli Chilakala" <mallikarjuna.chilakala@intel.com>
Sender: netdev-bounce@xxxxxxxxxxx
3 Avoid race condition between e1000_watchdog and e1000_clean_tx_irq
Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala@xxxxxxxxx>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@xxxxxxxxx>
Signed-off-by: John Ronciak <john.ronciak@xxxxxxxxx>
diff -up net-drivers-2.4/drivers/net/e1000/e1000.h 
net-drivers-2.4/drivers/net/e1000.new/e1000.h
--- net-drivers-2.4/drivers/net/e1000/e1000.h   2005-02-01 23:21:49.120102160 
-0800
+++ net-drivers-2.4/drivers/net/e1000.new/e1000.h       2005-02-01 
23:21:50.386909576 -0800
@@ -224,6 +224,7 @@ struct e1000_adapter {
        uint32_t tx_fifo_size;
        atomic_t tx_fifo_stall;
        boolean_t pcix_82544;
+       boolean_t detect_tx_hung;
 
        /* RX */
        struct e1000_desc_ring rx_ring;
diff -up net-drivers-2.4/drivers/net/e1000/e1000_main.c 
net-drivers-2.4/drivers/net/e1000.new/e1000_main.c
--- net-drivers-2.4/drivers/net/e1000/e1000_main.c      2005-02-01 
23:21:49.122101856 -0800
+++ net-drivers-2.4/drivers/net/e1000.new/e1000_main.c  2005-02-01 
23:21:50.517889664 -0800
@@ -1422,7 +1422,6 @@ e1000_watchdog(unsigned long data)
        struct e1000_adapter *adapter = (struct e1000_adapter *) data;
        struct net_device *netdev = adapter->netdev;
        struct e1000_desc_ring *txdr = &adapter->tx_ring;
-       unsigned int i;
        uint32_t link;
 
        e1000_check_for_link(&adapter->hw);
@@ -1502,12 +1501,8 @@ e1000_watchdog(unsigned long data)
        /* Cause software interrupt to ensure rx ring is cleaned */
        E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
 
-       /* Early detection of hung controller */
-       i = txdr->next_to_clean;
-       if(txdr->buffer_info[i].dma &&
-          time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
-          !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
-               netif_stop_queue(netdev);
+       /* Force detection of hung controller every watchdog period*/
+       adapter->detect_tx_hung = TRUE;
 
        /* Reset the timer */
        mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -2226,6 +2221,16 @@ e1000_clean_tx_irq(struct e1000_adapter 
                netif_wake_queue(netdev);
 
        spin_unlock(&adapter->tx_lock);
+ 
+       if(adapter->detect_tx_hung) {
+               /* detect a transmit hang in hardware, this serializes the
+                * check with the clearing of time_stamp and movement of i */
+               adapter->detect_tx_hung = FALSE;
+               if(tx_ring->buffer_info[i].dma &&
+                  time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) 
&&
+                  !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
+                       netif_stop_queue(netdev);
+       }
 
        return cleaned;
 }
        




<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH net-drivers-2.4 3/10] e1000: Avoid race between e1000_watchdog and e1000_clean_tx_irq, Malli Chilakala <=