RDMA/cxgb3: Connection termination fixes
authorSteve Wise <swise@opengridcomputing.com>
Wed, 11 Feb 2009 00:38:57 +0000 (16:38 -0800)
committerRoland Dreier <rolandd@cisco.com>
Wed, 11 Feb 2009 00:38:57 +0000 (16:38 -0800)
The poll and flush code needs to handle all send opcodes: SEND,
SEND_WITH_SE, SEND_WITH_INV, and SEND_WITH_SE_INV.

Ignore TERM indications if the connection already gone.

Ignore HW receive completions if the RQ is empty.

Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/cxgb3/cxio_hal.c
drivers/infiniband/hw/cxgb3/cxio_wr.h
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb3/iwch_ev.c

index 4dcf08b3fd832dd12d96a5a5ce3c9dcc1c8a5058..c2740e790f733782830d2adf8dbbfbaba8c4259b 100644 (file)
@@ -450,7 +450,7 @@ static int cqe_completes_wr(struct t3_cqe *cqe, struct t3_wq *wq)
        if ((CQE_OPCODE(*cqe) == T3_READ_RESP) && SQ_TYPE(*cqe))
                return 0;
 
-       if ((CQE_OPCODE(*cqe) == T3_SEND) && RQ_TYPE(*cqe) &&
+       if (CQE_SEND_OPCODE(*cqe) && RQ_TYPE(*cqe) &&
            Q_EMPTY(wq->rq_rptr, wq->rq_wptr))
                return 0;
 
@@ -1204,11 +1204,12 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
                }
 
                /* incoming SEND with no receive posted failures */
-               if ((CQE_OPCODE(*hw_cqe) == T3_SEND) && RQ_TYPE(*hw_cqe) &&
+               if (CQE_SEND_OPCODE(*hw_cqe) && RQ_TYPE(*hw_cqe) &&
                    Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
                        ret = -1;
                        goto skip_cqe;
                }
+               BUG_ON((*cqe_flushed == 0) && !SW_CQE(*hw_cqe));
                goto proc_cqe;
        }
 
@@ -1223,6 +1224,13 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
                 * then we complete this with TPT_ERR_MSN and mark the wq in
                 * error.
                 */
+
+               if (Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
+                       wq->error = 1;
+                       ret = -1;
+                       goto skip_cqe;
+               }
+
                if (unlikely((CQE_WRID_MSN(*hw_cqe) != (wq->rq_rptr + 1)))) {
                        wq->error = 1;
                        hw_cqe->header |= htonl(V_CQE_STATUS(TPT_ERR_MSN));
@@ -1277,6 +1285,7 @@ proc_cqe:
                        cxio_hal_pblpool_free(wq->rdev,
                                wq->rq[Q_PTR2IDX(wq->rq_rptr,
                                wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE);
+               BUG_ON(Q_EMPTY(wq->rq_rptr, wq->rq_wptr));
                wq->rq_rptr++;
        }
 
index 04618f7bfbb323fc9cdd3ec44046ebb952813457..ff9be1a13106cf757f12209f1343d7d63059ec96 100644 (file)
@@ -604,6 +604,12 @@ struct t3_cqe {
 #define CQE_STATUS(x)     (G_CQE_STATUS(be32_to_cpu((x).header)))
 #define CQE_OPCODE(x)     (G_CQE_OPCODE(be32_to_cpu((x).header)))
 
+#define CQE_SEND_OPCODE(x)( \
+       (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND) || \
+       (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE) || \
+       (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_INV) || \
+       (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE_INV))
+
 #define CQE_LEN(x)        (be32_to_cpu((x).len))
 
 /* used for RQ completion processing */
index 44e936e48a313d023964459ce36b0cf7c4b668d9..8699947aaf6cdfa036295d0b9dfbb49b54a30625 100644 (file)
@@ -1678,6 +1678,9 @@ static int terminate(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
 {
        struct iwch_ep *ep = ctx;
 
+       if (state_read(&ep->com) != FPDU_MODE)
+               return CPL_RET_BUF_DONE;
+
        PDBG("%s ep %p\n", __func__, ep);
        skb_pull(skb, sizeof(struct cpl_rdma_terminate));
        PDBG("%s saving %d bytes of term msg\n", __func__, skb->len);
index 7b67a67717209424dc9493a1c27cd18861b833d3..743c5d8b880686a11357e5ed39c50a60ffde91a2 100644 (file)
@@ -179,11 +179,6 @@ void iwch_ev_dispatch(struct cxio_rdev *rdev_p, struct sk_buff *skb)
        case TPT_ERR_BOUND:
        case TPT_ERR_INVALIDATE_SHARED_MR:
        case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
-               printk(KERN_ERR "%s - CQE Err qpid 0x%x opcode %d status 0x%x "
-                      "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __func__,
-                      CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
-                      CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
-                      CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
                (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
                post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1);
                break;