[openib-commits] r335 - gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib

roland at openib.org
Wed Jun 30 11:07:00 PDT 2004


Author: roland
Date: 2004-06-30 11:06:59 -0700 (Wed, 30 Jun 2004)
New Revision: 335

Modified:
   gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib.h
   gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib_ib.c
   gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib_main.c
Log:
Fix race condition where send queue state could be incorrectly
started or stopped after condition has already changed.


Modified: gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib.h    2004-06-30 05:06:36 UTC (rev 334)
+++ gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib.h    2004-06-30 18:06:59 UTC (rev 335)
@@ -147,7 +147,7 @@
 
        struct ipoib_tx_buf *tx_ring;
        int tx_head;
-       atomic_t tx_free;
+       int tx_free;
 
        struct ipoib_sarp_cache *sarp_cache;
 

Modified: gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib_ib.c
===================================================================
--- gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib_ib.c 2004-06-30 05:06:36 UTC (rev 334)
+++ gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib_ib.c 2004-06-30 18:06:59 UTC (rev 335)
@@ -223,6 +223,7 @@
        case IB_COMPLETION_OP_SEND:
        {
                struct ipoib_tx_buf *tx_req;
+               unsigned long flags;
 
                if (work_request_id >= IPOIB_TX_RING_SIZE) {
                        TS_REPORT_WARN(MOD_IB_NET,
@@ -255,9 +256,11 @@
                tx_req->callback = NULL;
                tx_req->ptr = NULL;
 
-               atomic_inc(&priv->tx_free);
-               if (atomic_read(&priv->tx_free) > IPOIB_TX_RING_SIZE / 2)
+               spin_lock_irqsave(&priv->lock, flags);
+               ++priv->tx_free;
+               if (priv->tx_free > IPOIB_TX_RING_SIZE / 2)
                        netif_wake_queue(dev);
+               spin_unlock_irqrestore(&priv->lock, flags);
 
                break;
        }
@@ -365,16 +368,21 @@
                tx_req->callback = NULL;
                tx_req->ptr = NULL;
        } else {
+               unsigned long flags;
+
                dev->trans_start = jiffies;
 
                priv->tx_head = (priv->tx_head + 1) % IPOIB_TX_RING_SIZE;
 
-               if (atomic_dec_and_test(&priv->tx_free)) {
+               spin_lock_irqsave(&priv->lock, flags);
+               --priv->tx_free;
+               if (priv->tx_free == 0) {
                        TS_TRACE(MOD_IB_NET, T_VERY_VERBOSE, TRACE_IB_NET_GEN,
                                 "%s: TX ring full, stopping Linux queue",
                                 dev->name);
                        netif_stop_queue(dev);
                }
+               spin_unlock_irqrestore(&priv->lock, flags);
 
                return 0;
        }

Modified: gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib_main.c       2004-06-30 05:06:36 UTC (rev 334)
+++ gen1/trunk/src/linux-kernel/infiniband/ulp/ipoib/ipoib_main.c       2004-06-30 18:06:59 UTC (rev 335)
@@ -385,8 +385,7 @@
 {
        struct ipoib_dev_priv *priv = dev->priv;
 
-       if (atomic_read(&priv->tx_free)
-           && !test_bit(IPOIB_FLAG_TIMEOUT, &priv->flags)) {
+       if (priv->tx_free && !test_bit(IPOIB_FLAG_TIMEOUT, &priv->flags)) {
                char ring[IPOIB_TX_RING_SIZE + 1];
                int i;
 
@@ -398,7 +397,7 @@
                TS_REPORT_WARN(MOD_IB_NET,
                               "%s: transmit timeout: latency %ld, tx_free %d, tx_ring [%s]",
                               dev->name, jiffies - dev->trans_start,
-                              atomic_read(&priv->tx_free), ring);
+                              priv->tx_free, ring);
 
                set_bit(IPOIB_FLAG_TIMEOUT, &priv->flags);
        } else
@@ -515,7 +514,7 @@
        /* set up the rest of our private data */
 
        /* priv->tx_head is already 0 */
-       atomic_set(&priv->tx_free, IPOIB_TX_RING_SIZE);
+       priv->tx_free = IPOIB_TX_RING_SIZE;
 
        if (ipoib_ib_dev_init(dev, ca, port))
                goto out_tx_ring_cleanup;



More information about the openib-commits mailing list