[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