@@ -14,7 +14,10 @@
struct rxe_pkt_info {
struct rxe_dev *rxe; /* device that owns packet */
struct rxe_qp *qp; /* qp that owns packet */
- struct rxe_send_wqe *wqe; /* send wqe */
+ union {
+ struct rxe_send_wqe *wqe; /* send wqe */
+ struct rxe_srq *srq; /* srq for recvd xrc packets */
+ };
u8 *hdr; /* points to bth */
u32 mask; /* useful info about pkt */
u32 psn; /* bth psn of packet */
@@ -13,49 +13,51 @@
static int check_type_state(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
struct rxe_qp *qp)
{
- unsigned int pkt_type;
+ unsigned int pkt_type = pkt->opcode & IB_OPCODE_TYPE;
if (unlikely(!qp->valid))
- goto err1;
+ goto err_out;
- pkt_type = pkt->opcode & 0xe0;
switch (qp_type(qp)) {
case IB_QPT_RC:
- if (unlikely(pkt_type != IB_OPCODE_RC)) {
- pr_warn_ratelimited("bad qp type\n");
- goto err1;
- }
+ if (unlikely(pkt_type != IB_OPCODE_RC))
+ goto err_out;
break;
case IB_QPT_UC:
- if (unlikely(pkt_type != IB_OPCODE_UC)) {
- pr_warn_ratelimited("bad qp type\n");
- goto err1;
- }
+ if (unlikely(pkt_type != IB_OPCODE_UC))
+ goto err_out;
break;
case IB_QPT_UD:
case IB_QPT_GSI:
- if (unlikely(pkt_type != IB_OPCODE_UD)) {
- pr_warn_ratelimited("bad qp type\n");
- goto err1;
- }
+ if (unlikely(pkt_type != IB_OPCODE_UD))
+ goto err_out;
+ break;
+ case IB_QPT_XRC_INI:
+ if (unlikely(pkt_type != IB_OPCODE_XRC))
+ goto err_out;
+ break;
+ case IB_QPT_XRC_TGT:
+ if (unlikely(pkt_type != IB_OPCODE_XRC))
+ goto err_out;
break;
default:
- pr_warn_ratelimited("unsupported qp type\n");
- goto err1;
+ goto err_out;
}
if (pkt->mask & RXE_REQ_MASK) {
if (unlikely(qp->resp.state != QP_STATE_READY))
- goto err1;
+ goto err_out;
} else if (unlikely(qp->req.state < QP_STATE_READY ||
qp->req.state > QP_STATE_DRAINED)) {
- goto err1;
+ goto err_out;
}
return 0;
-err1:
+err_out:
+ pr_debug("%s: failed qp#%d: opcode = 0x%02x\n", __func__,
+ qp->elem.index, pkt->opcode);
return -EINVAL;
}
@@ -166,6 +168,37 @@ static int check_addr(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
return -EINVAL;
}
+static int check_xrcd(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
+ struct rxe_qp *qp)
+{
+ int err;
+
+ struct rxe_xrcd *xrcd = qp->xrcd;
+ u32 srqn = xrceth_srqn(pkt);
+ struct rxe_srq *srq;
+
+ srq = rxe_pool_get_index(&rxe->srq_pool, srqn);
+ if (unlikely(!srq)) {
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ if (unlikely(srq->xrcd != xrcd)) {
+ rxe_put(srq);
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ pkt->srq = srq;
+
+ return 0;
+
+err_out:
+ pr_debug("%s: qp#%d: failed err = %d\n", __func__,
+ qp->elem.index, err);
+ return err;
+}
+
static int hdr_check(struct rxe_pkt_info *pkt)
{
struct rxe_dev *rxe = pkt->rxe;
@@ -205,6 +238,12 @@ static int hdr_check(struct rxe_pkt_info *pkt)
err = check_keys(rxe, pkt, qpn, qp);
if (unlikely(err))
goto err2;
+
+ if (qp_type(qp) == IB_QPT_XRC_TGT) {
+ err = check_xrcd(rxe, pkt, qp);
+ if (unlikely(err))
+ goto err2;
+ }
} else {
if (unlikely((pkt->mask & RXE_GRH_MASK) == 0)) {
pr_warn_ratelimited("no grh for mcast qpn\n");
Extend rxe_recv.c to support xrc packets. Add checks for qp type and check qp->xrcd matches srq->xrcd. Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com> --- drivers/infiniband/sw/rxe/rxe_hdr.h | 5 +- drivers/infiniband/sw/rxe/rxe_recv.c | 79 +++++++++++++++++++++------- 2 files changed, 63 insertions(+), 21 deletions(-)