aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/svc_rdma.h1
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c58
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c12
3 files changed, 65 insertions, 6 deletions
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index 3584bc8864c4..cc3ae16eac68 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -137,6 +137,7 @@ struct svcxprt_rdma {
137 int sc_ord; /* RDMA read limit */ 137 int sc_ord; /* RDMA read limit */
138 int sc_max_sge; 138 int sc_max_sge;
139 int sc_max_sge_rd; /* max sge for read target */ 139 int sc_max_sge_rd; /* max sge for read target */
140 bool sc_snd_w_inv; /* OK to use Send With Invalidate */
140 141
141 atomic_t sc_sq_count; /* Number of SQ WR on queue */ 142 atomic_t sc_sq_count; /* Number of SQ WR on queue */
142 unsigned int sc_sq_depth; /* Depth of SQ */ 143 unsigned int sc_sq_depth; /* Depth of SQ */
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 3b95b19fcf72..f5a91edcd233 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -225,6 +225,48 @@ svc_rdma_get_reply_array(struct rpcrdma_msg *rmsgp,
225 return rp_ary; 225 return rp_ary;
226} 226}
227 227
228/* RPC-over-RDMA Version One private extension: Remote Invalidation.
229 * Responder's choice: requester signals it can handle Send With
230 * Invalidate, and responder chooses one rkey to invalidate.
231 *
232 * Find a candidate rkey to invalidate when sending a reply. Picks the
233 * first rkey it finds in the chunks lists.
234 *
235 * Returns zero if RPC's chunk lists are empty.
236 */
237static u32 svc_rdma_get_inv_rkey(struct rpcrdma_msg *rdma_argp,
238 struct rpcrdma_write_array *wr_ary,
239 struct rpcrdma_write_array *rp_ary)
240{
241 struct rpcrdma_read_chunk *rd_ary;
242 struct rpcrdma_segment *arg_ch;
243 u32 inv_rkey;
244
245 inv_rkey = 0;
246
247 rd_ary = svc_rdma_get_read_chunk(rdma_argp);
248 if (rd_ary) {
249 inv_rkey = be32_to_cpu(rd_ary->rc_target.rs_handle);
250 goto out;
251 }
252
253 if (wr_ary && be32_to_cpu(wr_ary->wc_nchunks)) {
254 arg_ch = &wr_ary->wc_array[0].wc_target;
255 inv_rkey = be32_to_cpu(arg_ch->rs_handle);
256 goto out;
257 }
258
259 if (rp_ary && be32_to_cpu(rp_ary->wc_nchunks)) {
260 arg_ch = &rp_ary->wc_array[0].wc_target;
261 inv_rkey = be32_to_cpu(arg_ch->rs_handle);
262 goto out;
263 }
264
265out:
266 dprintk("svcrdma: Send With Invalidate rkey=%08x\n", inv_rkey);
267 return inv_rkey;
268}
269
228/* Assumptions: 270/* Assumptions:
229 * - The specified write_len can be represented in sc_max_sge * PAGE_SIZE 271 * - The specified write_len can be represented in sc_max_sge * PAGE_SIZE
230 */ 272 */
@@ -464,7 +506,8 @@ static int send_reply(struct svcxprt_rdma *rdma,
464 struct page *page, 506 struct page *page,
465 struct rpcrdma_msg *rdma_resp, 507 struct rpcrdma_msg *rdma_resp,
466 struct svc_rdma_req_map *vec, 508 struct svc_rdma_req_map *vec,
467 int byte_count) 509 int byte_count,
510 u32 inv_rkey)
468{ 511{
469 struct svc_rdma_op_ctxt *ctxt; 512 struct svc_rdma_op_ctxt *ctxt;
470 struct ib_send_wr send_wr; 513 struct ib_send_wr send_wr;
@@ -535,7 +578,11 @@ static int send_reply(struct svcxprt_rdma *rdma,
535 send_wr.wr_cqe = &ctxt->cqe; 578 send_wr.wr_cqe = &ctxt->cqe;
536 send_wr.sg_list = ctxt->sge; 579 send_wr.sg_list = ctxt->sge;
537 send_wr.num_sge = sge_no; 580 send_wr.num_sge = sge_no;
538 send_wr.opcode = IB_WR_SEND; 581 if (inv_rkey) {
582 send_wr.opcode = IB_WR_SEND_WITH_INV;
583 send_wr.ex.invalidate_rkey = inv_rkey;
584 } else
585 send_wr.opcode = IB_WR_SEND;
539 send_wr.send_flags = IB_SEND_SIGNALED; 586 send_wr.send_flags = IB_SEND_SIGNALED;
540 587
541 ret = svc_rdma_send(rdma, &send_wr); 588 ret = svc_rdma_send(rdma, &send_wr);
@@ -567,6 +614,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
567 int inline_bytes; 614 int inline_bytes;
568 struct page *res_page; 615 struct page *res_page;
569 struct svc_rdma_req_map *vec; 616 struct svc_rdma_req_map *vec;
617 u32 inv_rkey;
570 618
571 dprintk("svcrdma: sending response for rqstp=%p\n", rqstp); 619 dprintk("svcrdma: sending response for rqstp=%p\n", rqstp);
572 620
@@ -577,6 +625,10 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
577 wr_ary = svc_rdma_get_write_array(rdma_argp); 625 wr_ary = svc_rdma_get_write_array(rdma_argp);
578 rp_ary = svc_rdma_get_reply_array(rdma_argp, wr_ary); 626 rp_ary = svc_rdma_get_reply_array(rdma_argp, wr_ary);
579 627
628 inv_rkey = 0;
629 if (rdma->sc_snd_w_inv)
630 inv_rkey = svc_rdma_get_inv_rkey(rdma_argp, wr_ary, rp_ary);
631
580 /* Build an req vec for the XDR */ 632 /* Build an req vec for the XDR */
581 vec = svc_rdma_get_req_map(rdma); 633 vec = svc_rdma_get_req_map(rdma);
582 ret = svc_rdma_map_xdr(rdma, &rqstp->rq_res, vec, wr_ary != NULL); 634 ret = svc_rdma_map_xdr(rdma, &rqstp->rq_res, vec, wr_ary != NULL);
@@ -619,7 +671,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
619 goto err1; 671 goto err1;
620 672
621 ret = send_reply(rdma, rqstp, res_page, rdma_resp, vec, 673 ret = send_reply(rdma, rqstp, res_page, rdma_resp, vec,
622 inline_bytes); 674 inline_bytes, inv_rkey);
623 if (ret < 0) 675 if (ret < 0)
624 goto err0; 676 goto err0;
625 677
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index f51e98a25263..b2464fc4c455 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -657,9 +657,14 @@ svc_rdma_parse_connect_private(struct svcxprt_rdma *newxprt,
657 if (pmsg && 657 if (pmsg &&
658 pmsg->cp_magic == rpcrdma_cmp_magic && 658 pmsg->cp_magic == rpcrdma_cmp_magic &&
659 pmsg->cp_version == RPCRDMA_CMP_VERSION) { 659 pmsg->cp_version == RPCRDMA_CMP_VERSION) {
660 dprintk("svcrdma: client send_size %u, recv_size %u\n", 660 newxprt->sc_snd_w_inv = pmsg->cp_flags &
661 RPCRDMA_CMP_F_SND_W_INV_OK;
662
663 dprintk("svcrdma: client send_size %u, recv_size %u "
664 "remote inv %ssupported\n",
661 rpcrdma_decode_buffer_size(pmsg->cp_send_size), 665 rpcrdma_decode_buffer_size(pmsg->cp_send_size),
662 rpcrdma_decode_buffer_size(pmsg->cp_recv_size)); 666 rpcrdma_decode_buffer_size(pmsg->cp_recv_size),
667 newxprt->sc_snd_w_inv ? "" : "un");
663 } 668 }
664} 669}
665 670
@@ -1093,7 +1098,8 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
1093 dev->attrs.max_fast_reg_page_list_len; 1098 dev->attrs.max_fast_reg_page_list_len;
1094 newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG; 1099 newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG;
1095 newxprt->sc_reader = rdma_read_chunk_frmr; 1100 newxprt->sc_reader = rdma_read_chunk_frmr;
1096 } 1101 } else
1102 newxprt->sc_snd_w_inv = false;
1097 1103
1098 /* 1104 /*
1099 * Determine if a DMA MR is required and if so, what privs are required 1105 * Determine if a DMA MR is required and if so, what privs are required