diff options
author | Steve Wise <swise@opengridcomputing.com> | 2009-02-10 19:38:57 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-02-10 19:38:57 -0500 |
commit | 42fb61f02f9bdc476c7a76d3cce0400d989f44c5 (patch) | |
tree | 1b65628292881e77e81f6e1bdc6aed64b38f0646 /drivers/infiniband/hw | |
parent | 900f4c16c338f742b80f3aa500e12ceb017e86af (diff) |
RDMA/cxgb3: Connection termination fixes
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>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/cxgb3/cxio_hal.c | 13 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/cxio_wr.h | 6 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_cm.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_ev.c | 5 |
4 files changed, 20 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 4dcf08b3fd83..c2740e790f73 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c | |||
@@ -450,7 +450,7 @@ static int cqe_completes_wr(struct t3_cqe *cqe, struct t3_wq *wq) | |||
450 | if ((CQE_OPCODE(*cqe) == T3_READ_RESP) && SQ_TYPE(*cqe)) | 450 | if ((CQE_OPCODE(*cqe) == T3_READ_RESP) && SQ_TYPE(*cqe)) |
451 | return 0; | 451 | return 0; |
452 | 452 | ||
453 | if ((CQE_OPCODE(*cqe) == T3_SEND) && RQ_TYPE(*cqe) && | 453 | if (CQE_SEND_OPCODE(*cqe) && RQ_TYPE(*cqe) && |
454 | Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) | 454 | Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) |
455 | return 0; | 455 | return 0; |
456 | 456 | ||
@@ -1204,11 +1204,12 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe, | |||
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | /* incoming SEND with no receive posted failures */ | 1206 | /* incoming SEND with no receive posted failures */ |
1207 | if ((CQE_OPCODE(*hw_cqe) == T3_SEND) && RQ_TYPE(*hw_cqe) && | 1207 | if (CQE_SEND_OPCODE(*hw_cqe) && RQ_TYPE(*hw_cqe) && |
1208 | Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) { | 1208 | Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) { |
1209 | ret = -1; | 1209 | ret = -1; |
1210 | goto skip_cqe; | 1210 | goto skip_cqe; |
1211 | } | 1211 | } |
1212 | BUG_ON((*cqe_flushed == 0) && !SW_CQE(*hw_cqe)); | ||
1212 | goto proc_cqe; | 1213 | goto proc_cqe; |
1213 | } | 1214 | } |
1214 | 1215 | ||
@@ -1223,6 +1224,13 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe, | |||
1223 | * then we complete this with TPT_ERR_MSN and mark the wq in | 1224 | * then we complete this with TPT_ERR_MSN and mark the wq in |
1224 | * error. | 1225 | * error. |
1225 | */ | 1226 | */ |
1227 | |||
1228 | if (Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) { | ||
1229 | wq->error = 1; | ||
1230 | ret = -1; | ||
1231 | goto skip_cqe; | ||
1232 | } | ||
1233 | |||
1226 | if (unlikely((CQE_WRID_MSN(*hw_cqe) != (wq->rq_rptr + 1)))) { | 1234 | if (unlikely((CQE_WRID_MSN(*hw_cqe) != (wq->rq_rptr + 1)))) { |
1227 | wq->error = 1; | 1235 | wq->error = 1; |
1228 | hw_cqe->header |= htonl(V_CQE_STATUS(TPT_ERR_MSN)); | 1236 | hw_cqe->header |= htonl(V_CQE_STATUS(TPT_ERR_MSN)); |
@@ -1277,6 +1285,7 @@ proc_cqe: | |||
1277 | cxio_hal_pblpool_free(wq->rdev, | 1285 | cxio_hal_pblpool_free(wq->rdev, |
1278 | wq->rq[Q_PTR2IDX(wq->rq_rptr, | 1286 | wq->rq[Q_PTR2IDX(wq->rq_rptr, |
1279 | wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE); | 1287 | wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE); |
1288 | BUG_ON(Q_EMPTY(wq->rq_rptr, wq->rq_wptr)); | ||
1280 | wq->rq_rptr++; | 1289 | wq->rq_rptr++; |
1281 | } | 1290 | } |
1282 | 1291 | ||
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index 04618f7bfbb3..ff9be1a13106 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h | |||
@@ -604,6 +604,12 @@ struct t3_cqe { | |||
604 | #define CQE_STATUS(x) (G_CQE_STATUS(be32_to_cpu((x).header))) | 604 | #define CQE_STATUS(x) (G_CQE_STATUS(be32_to_cpu((x).header))) |
605 | #define CQE_OPCODE(x) (G_CQE_OPCODE(be32_to_cpu((x).header))) | 605 | #define CQE_OPCODE(x) (G_CQE_OPCODE(be32_to_cpu((x).header))) |
606 | 606 | ||
607 | #define CQE_SEND_OPCODE(x)( \ | ||
608 | (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND) || \ | ||
609 | (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE) || \ | ||
610 | (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_INV) || \ | ||
611 | (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE_INV)) | ||
612 | |||
607 | #define CQE_LEN(x) (be32_to_cpu((x).len)) | 613 | #define CQE_LEN(x) (be32_to_cpu((x).len)) |
608 | 614 | ||
609 | /* used for RQ completion processing */ | 615 | /* used for RQ completion processing */ |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 44e936e48a31..8699947aaf6c 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -1678,6 +1678,9 @@ static int terminate(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1678 | { | 1678 | { |
1679 | struct iwch_ep *ep = ctx; | 1679 | struct iwch_ep *ep = ctx; |
1680 | 1680 | ||
1681 | if (state_read(&ep->com) != FPDU_MODE) | ||
1682 | return CPL_RET_BUF_DONE; | ||
1683 | |||
1681 | PDBG("%s ep %p\n", __func__, ep); | 1684 | PDBG("%s ep %p\n", __func__, ep); |
1682 | skb_pull(skb, sizeof(struct cpl_rdma_terminate)); | 1685 | skb_pull(skb, sizeof(struct cpl_rdma_terminate)); |
1683 | PDBG("%s saving %d bytes of term msg\n", __func__, skb->len); | 1686 | PDBG("%s saving %d bytes of term msg\n", __func__, skb->len); |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c index 7b67a6771720..743c5d8b8806 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_ev.c +++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c | |||
@@ -179,11 +179,6 @@ void iwch_ev_dispatch(struct cxio_rdev *rdev_p, struct sk_buff *skb) | |||
179 | case TPT_ERR_BOUND: | 179 | case TPT_ERR_BOUND: |
180 | case TPT_ERR_INVALIDATE_SHARED_MR: | 180 | case TPT_ERR_INVALIDATE_SHARED_MR: |
181 | case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND: | 181 | case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND: |
182 | printk(KERN_ERR "%s - CQE Err qpid 0x%x opcode %d status 0x%x " | ||
183 | "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __func__, | ||
184 | CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe), | ||
185 | CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe), | ||
186 | CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe)); | ||
187 | (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); | 182 | (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); |
188 | post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1); | 183 | post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1); |
189 | break; | 184 | break; |