[openib-general] [PATCH] (final) reduce qp locking on cq poll

Michael S. Tsirkin mst at mellanox.co.il
Wed Jan 26 11:44:01 PST 2005


Here it is, fixed. Untested, but I only touched the comments ...

> >     Michael> Locking during the poll cq operation can be reduced, by
> >     Michael> locking the cq while qp is being removed from the qp
> >     Michael> array.  This also avoids an extra atomic operation for
> >     Michael> reference counting.

Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>

Index: hw/mthca/mthca_cq.c
===================================================================
--- hw/mthca/mthca_cq.c	(revision 1663)
+++ hw/mthca/mthca_cq.c	(working copy)
@@ -420,14 +420,11 @@ static inline int mthca_poll_one(struct 
 				wake_up(&(*cur_qp)->wait);
 		}
 
-		spin_lock(&dev->qp_table.lock);
+		/* We do not have to take the qp table lock here, because
+		   cq was locked while qp was removed from the array */
 		*cur_qp = mthca_array_get(&dev->qp_table.qp,
 					  be32_to_cpu(cqe->my_qpn) &
 					  (dev->limits.num_qps - 1));
-		if (*cur_qp)
-			atomic_inc(&(*cur_qp)->refcount);
-		spin_unlock(&dev->qp_table.lock);
-
 		if (!*cur_qp) {
 			mthca_warn(dev, "CQ entry for unknown QP %06x\n",
 				   be32_to_cpu(cqe->my_qpn) & 0xffffff);
@@ -541,8 +538,6 @@ int mthca_poll_cq(struct ib_cq *ibcq, in
 
 	if (qp) {
 		spin_unlock(&qp->lock);
-		if (atomic_dec_and_test(&qp->refcount))
-			wake_up(&qp->wait);
 	}
 
 
Index: hw/mthca/TODO
===================================================================
--- hw/mthca/TODO	(revision 1663)
+++ hw/mthca/TODO	(working copy)
@@ -11,11 +11,6 @@ Small projects (extensions to existing c
         into HCA memory.
     Miscellaneous verbs: At least query AH, query QP and resize CQ are
         not implemented.
-    Reduce locking for CQ poll: The reference counting used to prevent
-        CQs and QPs from being destroyed while events are being
-        dispatched could be eliminated by locking EQs (and, for QPs,
-        the associated CQs) during destroy operations.  This saves an
-        atomic access in the CQ poll fast path.
     Reduce doorbell locking on 32-bit architectures: By using a
         a doorbell page dedicated to each EQ, no lock is required in
         the EQ poll path.
Index: hw/mthca/mthca_qp.c
===================================================================
--- hw/mthca/mthca_qp.c	(revision 1663)
+++ hw/mthca/mthca_qp.c	(working copy)
@@ -1083,9 +1083,19 @@ int mthca_alloc_sqp(struct mthca_dev *de
 	return 0;
 
  err_out_free:
-	spin_lock_irq(&dev->qp_table.lock);
+	/* Lock cq here, so that cq polling code
+	   can do qp lookup without taking a lock */
+	spin_lock_irq(&send_cq->lock);
+	if (send_cq != recv_cq)
+		spin_lock(&recv_cq->lock);
+
+	spin_lock(&dev->qp_table.lock);
 	mthca_array_clear(&dev->qp_table.qp, mqpn);
-	spin_unlock_irq(&dev->qp_table.lock);
+	spin_unlock(&dev->qp_table.lock);
+
+	if (send_cq != recv_cq)
+		spin_unlock(&recv_cq->lock);
+	spin_unlock_irq(&send_cq->lock);
 
  err_out:
 	dma_free_coherent(&dev->pdev->dev, sqp->header_buf_size,
@@ -1100,11 +1110,26 @@ void mthca_free_qp(struct mthca_dev *dev
 	u8 status;
 	int size;
 	int i;
+	struct mthca_cq *send_cq;
+	struct mthca_cq *recv_cq;
+
+	send_cq = to_mcq(qp->ibqp.send_cq);
+	recv_cq = to_mcq(qp->ibqp.recv_cq);
 
-	spin_lock_irq(&dev->qp_table.lock);
+	/* Lock cq here, so that cq polling code
+	   can do qp lookup without taking a lock */
+	spin_lock_irq(&send_cq->lock);
+	if (send_cq != recv_cq)
+		spin_lock(&recv_cq->lock);
+
+	spin_lock(&dev->qp_table.lock);
 	mthca_array_clear(&dev->qp_table.qp,
 			  qp->qpn & (dev->limits.num_qps - 1));
-	spin_unlock_irq(&dev->qp_table.lock);
+	spin_unlock(&dev->qp_table.lock);
+
+	if (send_cq != recv_cq)
+		spin_unlock(&recv_cq->lock);
+	spin_unlock_irq(&send_cq->lock);
 
 	atomic_dec(&qp->refcount);
 	wait_event(qp->wait, !atomic_read(&qp->refcount));
-- 
I dont speak for Mellanox



More information about the general mailing list