aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/hfi1/ruc.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/ruc.c
parentIB/hfi1: Handle send with invalidate opcode in the RC recv path (diff)
downloadlinux-dev-0db3dfa03c0881fc98d3ff2f88dcca2bc69c0003.tar.xz
linux-dev-0db3dfa03c0881fc98d3ff2f88dcca2bc69c0003.zip
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/ruc.c')
-rw-r--r--drivers/infiniband/hw/hfi1/ruc.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c
index a659aec3c3c6..76b9c9e42d86 100644
--- a/drivers/infiniband/hw/hfi1/ruc.c
+++ b/drivers/infiniband/hw/hfi1/ruc.c
@@ -372,6 +372,7 @@ static void ruc_loopback(struct rvt_qp *sqp)
int ret;
int copy_last = 0;
u32 to;
+ int local_ops = 0;
rcu_read_lock();
@@ -440,11 +441,32 @@ again:
sqp->s_sge.num_sge = wqe->wr.num_sge;
sqp->s_len = wqe->length;
switch (wqe->wr.opcode) {
+ case IB_WR_REG_MR:
+ if (rvt_fast_reg_mr(sqp, wqe->reg_wr.mr, wqe->reg_wr.key,
+ wqe->reg_wr.access))
+ send_status = IB_WC_LOC_PROT_ERR;
+ local_ops = 1;
+ goto send_comp;
+
+ case IB_WR_LOCAL_INV:
+ if (rvt_invalidate_rkey(sqp, wqe->wr.ex.invalidate_rkey))
+ send_status = IB_WC_LOC_PROT_ERR;
+ local_ops = 1;
+ goto send_comp;
+
+ case IB_WR_SEND_WITH_INV:
+ if (!rvt_invalidate_rkey(qp, wqe->wr.ex.invalidate_rkey)) {
+ wc.wc_flags = IB_WC_WITH_INVALIDATE;
+ wc.ex.invalidate_rkey = wqe->wr.ex.invalidate_rkey;
+ }
+ goto send;
+
case IB_WR_SEND_WITH_IMM:
wc.wc_flags = IB_WC_WITH_IMM;
wc.ex.imm_data = wqe->wr.ex.imm_data;
/* FALLTHROUGH */
case IB_WR_SEND:
+send:
ret = hfi1_rvt_get_rwqe(qp, 0);
if (ret < 0)
goto op_err;
@@ -583,6 +605,10 @@ send_comp:
flush_send:
sqp->s_rnr_retry = sqp->s_rnr_retry_cnt;
hfi1_send_complete(sqp, wqe, send_status);
+ if (local_ops) {
+ atomic_dec(&sqp->local_ops_pending);
+ local_ops = 0;
+ }
goto again;
rnr_nak: