Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=dfd341e4e467d146901a3accb761f04fda535433
Commit:     dfd341e4e467d146901a3accb761f04fda535433
Parent:     5d9278537502d2e404e85485d1b905814fe728c0
Author:     Jesse Brandeburg <[EMAIL PROTECTED]>
AuthorDate: Sat Jan 6 09:51:38 2007 -0800
Committer:  Auke Kok <[EMAIL PROTECTED]>
CommitDate: Sat Jan 6 09:51:38 2007 -0800

    ixgb: Maybe stop TX if not enough free descriptors
    
    A similar patch to commit 65c7973fa5b46b024f38be208aa477e8daf9a603
    but now for ixgb.
    
    Cc: Herbert Xu <[EMAIL PROTECTED]>
    Signed-off-by: Jesse Brandeburg <[EMAIL PROTECTED]>
    Signed-off-by: Auke Kok <[EMAIL PROTECTED]>
---
 drivers/net/ixgb/ixgb.h         |    1 +
 drivers/net/ixgb/ixgb_ethtool.c |    1 +
 drivers/net/ixgb/ixgb_main.c    |   37 ++++++++++++++++++++++++++++++++++---
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index 50ffe90..f4aba43 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -171,6 +171,7 @@ struct ixgb_adapter {
 
        /* TX */
        struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp;
+       unsigned int restart_queue;
        unsigned long timeo_start;
        uint32_t tx_cmd_type;
        uint64_t hw_csum_tx_good;
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index cd22523..82c044d 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -79,6 +79,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
        {"tx_window_errors", IXGB_STAT(net_stats.tx_window_errors)},
        {"tx_deferred_ok", IXGB_STAT(stats.dc)},
        {"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
+       {"tx_restart_queue", IXGB_STAT(restart_queue) },
        {"rx_long_length_errors", IXGB_STAT(stats.roc)},
        {"rx_short_length_errors", IXGB_STAT(stats.ruc)},
 #ifdef NETIF_F_TSO
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 70ac9d4..16317b5 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1411,6 +1411,37 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, 
int vlan_id,int tx_flags)
        IXGB_WRITE_REG(&adapter->hw, TDT, i);
 }
 
+static int __ixgb_maybe_stop_tx(struct net_device *netdev, int size)
+{
+       struct ixgb_adapter *adapter = netdev_priv(netdev);
+       struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
+
+       netif_stop_queue(netdev);
+       /* Herbert's original patch had:
+        *  smp_mb__after_netif_stop_queue();
+        * but since that doesn't exist yet, just open code it. */
+       smp_mb();
+
+       /* We need to check again in a case another CPU has just
+        * made room available. */
+       if (likely(IXGB_DESC_UNUSED(tx_ring) < size))
+               return -EBUSY;
+
+       /* A reprieve! */
+       netif_start_queue(netdev);
+       ++adapter->restart_queue;
+       return 0;
+}
+
+static int ixgb_maybe_stop_tx(struct net_device *netdev,
+                              struct ixgb_desc_ring *tx_ring, int size)
+{
+       if (likely(IXGB_DESC_UNUSED(tx_ring) >= size))
+               return 0;
+       return __ixgb_maybe_stop_tx(netdev, size);
+}
+
+
 /* Tx Descriptors needed, worst case */
 #define TXD_USE_COUNT(S) (((S) >> IXGB_MAX_TXD_PWR) + \
                         (((S) & (IXGB_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
@@ -1444,7 +1475,8 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device 
*netdev)
        spin_lock_irqsave(&adapter->tx_lock, flags);
 #endif
 
-       if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
+       if (unlikely(ixgb_maybe_stop_tx(netdev, &adapter->tx_ring,
+                     DESC_NEEDED))) {
                netif_stop_queue(netdev);
                spin_unlock_irqrestore(&adapter->tx_lock, flags);
                return NETDEV_TX_BUSY;
@@ -1482,8 +1514,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device 
*netdev)
 
 #ifdef NETIF_F_LLTX
        /* Make sure there is space in the ring for the next send. */
-       if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED))
-               netif_stop_queue(netdev);
+       ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
 
        spin_unlock_irqrestore(&adapter->tx_lock, flags);
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to