[ofa-general] [PATCHv2 for-2.6.21] IB/mthca: QP reset fixes

Michael S. Tsirkin mst at mellanox.co.il
Thu Mar 1 06:41:39 PST 2007


Fix 2 issues related to QP reset:
1. After moving QP to reset, make sure no event handlers are in progress
2. In QP destroy, reset QP before removing it from QP table:
   otherwise we get bogus QP/unknown QP warnings
   (and theoretically, crash, if the same slot is reused with the same QPN).

This fixes openfabrics bugzilla 394.

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

---

Changeds wrt v1: since we use synchronize_irq, it is cleaner to
include linux/hardirq.h in qp.c directly.

Roland, please queue for 2.6.21. Link to bugzilla entry:
https://bugs.openfabrics.org/show_bug.cgi?id=394

diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 71dc84b..387af53 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -37,6 +37,7 @@
 
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/hardirq.h>
 
 #include <asm/io.h>
 
@@ -864,6 +865,12 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
 		if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
 			mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn, NULL);
 
+		if (dev->mthca_flags & MTHCA_FLAG_MSI_X) {
+			synchronize_irq(dev->eq_table.eq[MTHCA_EQ_COMP].msi_x_vector);
+			synchronize_irq(dev->eq_table.eq[MTHCA_EQ_ASYNC].msi_x_vector);
+		} else
+			synchronize_irq(dev->pdev->irq);
+
 		mthca_wq_reset(&qp->sq);
 		qp->sq.last = get_send_wqe(qp, qp->sq.max - 1);
 
@@ -1393,6 +1400,10 @@ void mthca_free_qp(struct mthca_dev *dev,
 	send_cq = to_mcq(qp->ibqp.send_cq);
 	recv_cq = to_mcq(qp->ibqp.recv_cq);
 
+	if (qp->state != IB_QPS_RESET)
+		mthca_MODIFY_QP(dev, qp->state, IB_QPS_RESET, qp->qpn, 0,
+				NULL, 0, &status);
+
 	/*
 	 * Lock CQs here, so that CQ polling code can do QP lookup
 	 * without taking a lock.
@@ -1409,10 +1420,6 @@ void mthca_free_qp(struct mthca_dev *dev,
 
 	wait_event(qp->wait, !get_qp_refcount(dev, qp));
 
-	if (qp->state != IB_QPS_RESET)
-		mthca_MODIFY_QP(dev, qp->state, IB_QPS_RESET, qp->qpn, 0,
-				NULL, 0, &status);
-
 	/*
 	 * If this is a userspace QP, the buffers, MR, CQs and so on
 	 * will be cleaned up in userspace, so all we have to do is
@@ -1425,6 +1432,12 @@ void mthca_free_qp(struct mthca_dev *dev,
 			mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn,
 				       qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
 
+		if (dev->mthca_flags & MTHCA_FLAG_MSI_X) {
+			synchronize_irq(dev->eq_table.eq[MTHCA_EQ_COMP].msi_x_vector);
+			synchronize_irq(dev->eq_table.eq[MTHCA_EQ_ASYNC].msi_x_vector);
+		} else
+			synchronize_irq(dev->pdev->irq);
+
 		mthca_free_memfree(dev, qp);
 		mthca_free_wqe_buf(dev, qp);
 	}
-- 
MST



More information about the general mailing list