summaryrefslogtreecommitdiff
path: root/drivers/infiniband/hw/hfi1/uc.c
diff options
context:
space:
mode:
authorJianxin Xiong <jianxin.xiong@intel.com>2016-07-25 13:38:37 -0700
committerDoug Ledford <dledford@redhat.com>2016-08-02 16:00:58 -0400
commit0db3dfa03c0881fc98d3ff2f88dcca2bc69c0003 (patch)
tree5c50914151b721cf77d5b791a73498be56ad97cc /drivers/infiniband/hw/hfi1/uc.c
parenta2df0c833209a22d020163913e451f94be5114cd (diff)
IB/hfi1: Work request processing for fast register mr and invalidate
In order to support extended memory management support, add send side processing of work requests of type IB_WR_REG_MR, IB_WR_LOCAL_INV, and IB_WR_SEND_WITH_INV. The first two are local operations and are supported for both RC and UC. Send with invalidate is only supported for RC because the corresponding IB opcodes are not defined for UC. Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Jianxin Xiong <jianxin.xiong@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/hw/hfi1/uc.c')
-rw-r--r--drivers/infiniband/hw/hfi1/uc.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/hfi1/uc.c b/drivers/infiniband/hw/hfi1/uc.c
index b7a25311bd7b..ef6c96cd3d68 100644
--- a/drivers/infiniband/hw/hfi1/uc.c
+++ b/drivers/infiniband/hw/hfi1/uc.c
@@ -77,6 +77,7 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
u32 len;
u32 pmtu = qp->pmtu;
int middle = 0;
+ int err;
ps->s_txreq = get_txreq(ps->dev, qp);
if (IS_ERR(ps->s_txreq))
@@ -119,6 +120,29 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
goto bail;
}
/*
+ * Local operations are processed immediately
+ * after all prior requests have completed.
+ */
+ if (wqe->wr.opcode == IB_WR_REG_MR ||
+ wqe->wr.opcode == IB_WR_LOCAL_INV) {
+ if (qp->s_last != qp->s_cur)
+ goto bail;
+ if (++qp->s_cur == qp->s_size)
+ qp->s_cur = 0;
+ if (wqe->wr.opcode == IB_WR_REG_MR)
+ err = rvt_fast_reg_mr(qp, wqe->reg_wr.mr,
+ wqe->reg_wr.key,
+ wqe->reg_wr.access);
+ else
+ err = rvt_invalidate_rkey(
+ qp, wqe->wr.ex.invalidate_rkey);
+ hfi1_send_complete(qp, wqe, err ? IB_WC_LOC_PROT_ERR
+ : IB_WC_SUCCESS);
+ atomic_dec(&qp->local_ops_pending);
+ qp->s_hdrwords = 0;
+ goto done_free_tx;
+ }
+ /*
* Start a new request.
*/
qp->s_psn = wqe->psn;