summaryrefslogtreecommitdiff
path: root/drivers/infiniband/sw/rdmavt/qp.c
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2017-05-12 09:20:31 -0700
committerDoug Ledford <dledford@redhat.com>2017-06-27 16:56:33 -0400
commit14fe13fcd3afb96b06809f280b586be1c998332c (patch)
treecf713910a88e99f3264dd3a28c041659b7b5c983 /drivers/infiniband/sw/rdmavt/qp.c
parent9039746cdf39dcbf2ddfcc4a68f729cbbbc853df (diff)
IB/rdmavt: Compress adjacent SGEs in rvt_lkey_ok()
SGEs that are contiguous needlessly consume driver dependent TX resources. The lkey validation logic is enhanced to compress the SGE that ends up in the send wqe when consecutive addresses are detected. The lkey validation API used to return 1 (success) or 0 (fail). The return value is now an -errno, 0 (compressed), or 1 (uncompressed). A additional argument is added to pass the last SQE for the compression. Loopback callers always pass a NULL to last_sge since the optimization is of little benefit in that situation. Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Brian Welty <brian.welty@intel.com> Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/sw/rdmavt/qp.c')
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
index 727e81cc2c8f..a3dd1e536860 100644
--- a/drivers/infiniband/sw/rdmavt/qp.c
+++ b/drivers/infiniband/sw/rdmavt/qp.c
@@ -1646,7 +1646,7 @@ static int rvt_post_one_wr(struct rvt_qp *qp,
struct rvt_pd *pd;
struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device);
u8 log_pmtu;
- int ret;
+ int ret, incr;
size_t cplen;
bool reserved_op;
int local_ops_delayed = 0;
@@ -1719,22 +1719,23 @@ static int rvt_post_one_wr(struct rvt_qp *qp,
wqe->length = 0;
j = 0;
if (wr->num_sge) {
+ struct rvt_sge *last_sge = NULL;
+
acc = wr->opcode >= IB_WR_RDMA_READ ?
IB_ACCESS_LOCAL_WRITE : 0;
for (i = 0; i < wr->num_sge; i++) {
u32 length = wr->sg_list[i].length;
- int ok;
if (length == 0)
continue;
- ok = rvt_lkey_ok(rkt, pd, &wqe->sg_list[j],
- &wr->sg_list[i], acc);
- if (!ok) {
- ret = -EINVAL;
- goto bail_inval_free;
- }
+ incr = rvt_lkey_ok(rkt, pd, &wqe->sg_list[j], last_sge,
+ &wr->sg_list[i], acc);
+ if (unlikely(incr < 0))
+ goto bail_lkey_error;
wqe->length += length;
- j++;
+ if (incr)
+ last_sge = &wqe->sg_list[j];
+ j += incr;
}
wqe->wr.num_sge = j;
}
@@ -1781,12 +1782,14 @@ static int rvt_post_one_wr(struct rvt_qp *qp,
wqe->wr.send_flags &= ~RVT_SEND_RESERVE_USED;
qp->s_avail--;
}
- trace_rvt_post_one_wr(qp, wqe);
+ trace_rvt_post_one_wr(qp, wqe, wr->num_sge);
smp_wmb(); /* see request builders */
qp->s_head = next;
return 0;
+bail_lkey_error:
+ ret = incr;
bail_inval_free:
/* release mr holds */
while (j) {