Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42fb61f0 authored by Steve Wise's avatar Steve Wise Committed by Roland Dreier
Browse files

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: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 900f4c16
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -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++;
	}

+6 −0
Original line number Diff line number Diff line
@@ -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 */
+3 −0
Original line number Diff line number Diff line
@@ -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);
+0 −5
Original line number Diff line number Diff line
@@ -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;