[HW] bug workaround: skip releasing of QP number upon a failure to destroy QP in...
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 27 May 2009 10:25:19 +0000 (10:25 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 27 May 2009 10:25:19 +0000 (10:25 +0000)
Otherwise it prevents the creation of new QPs.
This workaround will "leak" one bit in QP numbers' bit table.

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2199 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

hw/mlx4/kernel/bus/ib/qp.c
hw/mthca/kernel/mthca_qp.c

index 47378d2..bf29a89 100644 (file)
@@ -535,12 +535,15 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
                              int is_user)\r
 {\r
        struct mlx4_ib_cq *send_cq, *recv_cq;\r
+       int zombi = 0;\r
 \r
        if (qp->state != XIB_QPS_RESET)\r
                if (mlx4_qp_modify(dev->dev, NULL, to_mlx4_state(qp->state),\r
-                                  MLX4_QP_STATE_RST, NULL, 0, 0, &qp->mqp))\r
+                               MLX4_QP_STATE_RST, NULL, 0, 0, &qp->mqp)) {\r
                        printk(KERN_WARNING "mlx4_ib: modify QP %06x to RESET failed.\n",\r
-                              qp->mqp.qpn);\r
+                               qp->mqp.qpn);\r
+                       zombi = 1;\r
+               }\r
 \r
        send_cq = to_mcq(qp->ibqp.send_cq);\r
        recv_cq = to_mcq(qp->ibqp.recv_cq);\r
@@ -560,7 +563,7 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
 \r
        mlx4_qp_free(dev->dev, &qp->mqp);\r
 \r
-       if (!is_sqp(dev, qp))\r
+       if (!is_sqp(dev, qp) && !zombi )\r
                mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1);\r
 \r
        mlx4_mtt_cleanup(dev->dev, &qp->mtt);\r
index 240852e..d64f807 100644 (file)
@@ -1515,6 +1515,7 @@ void mthca_free_qp(struct mthca_dev *dev,
        u8 status;\r
        struct mthca_cq *send_cq;\r
        struct mthca_cq *recv_cq;\r
+       int zombi = 0;\r
        SPIN_LOCK_PREP(lhs);\r
        SPIN_LOCK_PREP(lhr);\r
        SPIN_LOCK_PREP(lht);\r
@@ -1543,7 +1544,11 @@ void mthca_free_qp(struct mthca_dev *dev,
        wait_event(&qp->wait, !atomic_read(&qp->refcount));\r
 \r
        if (qp->state != IBQPS_RESET) {\r
-               mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status);\r
+               if (mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status)) {\r
+                       HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_QP,("modify QP %06x to RESET failed.\n",\r
+                               qp->qpn));\r
+                       zombi = 1;\r
+               }\r
        }\r
 \r
        /*\r
@@ -1567,8 +1572,10 @@ void mthca_free_qp(struct mthca_dev *dev,
        if (is_sqp(dev, qp)) {\r
                atomic_dec(&(to_mpd(qp->ibqp.pd)->sqp_count));\r
                free_dma_mem_map(dev, &to_msqp(qp)->sg, PCI_DMA_BIDIRECTIONAL);\r
-       } else\r
-               mthca_free(&dev->qp_table.alloc, qp->qpn);\r
+       } else {\r
+               if ( !zombi )\r
+                       mthca_free(&dev->qp_table.alloc, qp->qpn);\r
+       }\r
 }\r
 \r
 static enum mthca_wr_opcode conv_ibal_wr_opcode(struct _ib_send_wr *wr)\r