diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2015-01-13 11:03:20 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2015-01-15 15:01:46 -0500 |
commit | e54524111f51eac1900cf91aca3d38a92a6b11c0 (patch) | |
tree | 9c743ddc7d54a9aaf35b66d3cfa727ecac00f749 /net | |
parent | e5523bd28101869c85856247fc120faaf72bd232 (diff) |
svcrdma: Plant reader function in struct svcxprt_rdma
The RDMA reader function doesn't change once an svcxprt_rdma is
instantiated. Instead of checking sc_devcap during every incoming
RPC, set the reader function once when the connection is accepted.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 71 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 2 |
2 files changed, 29 insertions, 44 deletions
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 577f8659ca30..c3aebc1bf0a6 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | |||
@@ -117,26 +117,16 @@ static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count) | |||
117 | return min_t(int, sge_count, xprt->sc_max_sge); | 117 | return min_t(int, sge_count, xprt->sc_max_sge); |
118 | } | 118 | } |
119 | 119 | ||
120 | typedef int (*rdma_reader_fn)(struct svcxprt_rdma *xprt, | ||
121 | struct svc_rqst *rqstp, | ||
122 | struct svc_rdma_op_ctxt *head, | ||
123 | int *page_no, | ||
124 | u32 *page_offset, | ||
125 | u32 rs_handle, | ||
126 | u32 rs_length, | ||
127 | u64 rs_offset, | ||
128 | int last); | ||
129 | |||
130 | /* Issue an RDMA_READ using the local lkey to map the data sink */ | 120 | /* Issue an RDMA_READ using the local lkey to map the data sink */ |
131 | static int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt, | 121 | int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt, |
132 | struct svc_rqst *rqstp, | 122 | struct svc_rqst *rqstp, |
133 | struct svc_rdma_op_ctxt *head, | 123 | struct svc_rdma_op_ctxt *head, |
134 | int *page_no, | 124 | int *page_no, |
135 | u32 *page_offset, | 125 | u32 *page_offset, |
136 | u32 rs_handle, | 126 | u32 rs_handle, |
137 | u32 rs_length, | 127 | u32 rs_length, |
138 | u64 rs_offset, | 128 | u64 rs_offset, |
139 | int last) | 129 | bool last) |
140 | { | 130 | { |
141 | struct ib_send_wr read_wr; | 131 | struct ib_send_wr read_wr; |
142 | int pages_needed = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT; | 132 | int pages_needed = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT; |
@@ -221,15 +211,15 @@ static int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt, | |||
221 | } | 211 | } |
222 | 212 | ||
223 | /* Issue an RDMA_READ using an FRMR to map the data sink */ | 213 | /* Issue an RDMA_READ using an FRMR to map the data sink */ |
224 | static int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt, | 214 | int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt, |
225 | struct svc_rqst *rqstp, | 215 | struct svc_rqst *rqstp, |
226 | struct svc_rdma_op_ctxt *head, | 216 | struct svc_rdma_op_ctxt *head, |
227 | int *page_no, | 217 | int *page_no, |
228 | u32 *page_offset, | 218 | u32 *page_offset, |
229 | u32 rs_handle, | 219 | u32 rs_handle, |
230 | u32 rs_length, | 220 | u32 rs_length, |
231 | u64 rs_offset, | 221 | u64 rs_offset, |
232 | int last) | 222 | bool last) |
233 | { | 223 | { |
234 | struct ib_send_wr read_wr; | 224 | struct ib_send_wr read_wr; |
235 | struct ib_send_wr inv_wr; | 225 | struct ib_send_wr inv_wr; |
@@ -374,9 +364,9 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt, | |||
374 | { | 364 | { |
375 | int page_no, ret; | 365 | int page_no, ret; |
376 | struct rpcrdma_read_chunk *ch; | 366 | struct rpcrdma_read_chunk *ch; |
377 | u32 page_offset, byte_count; | 367 | u32 handle, page_offset, byte_count; |
378 | u64 rs_offset; | 368 | u64 rs_offset; |
379 | rdma_reader_fn reader; | 369 | bool last; |
380 | 370 | ||
381 | /* If no read list is present, return 0 */ | 371 | /* If no read list is present, return 0 */ |
382 | ch = svc_rdma_get_read_chunk(rmsgp); | 372 | ch = svc_rdma_get_read_chunk(rmsgp); |
@@ -399,27 +389,20 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt, | |||
399 | head->arg.len = rqstp->rq_arg.len; | 389 | head->arg.len = rqstp->rq_arg.len; |
400 | head->arg.buflen = rqstp->rq_arg.buflen; | 390 | head->arg.buflen = rqstp->rq_arg.buflen; |
401 | 391 | ||
402 | /* Use FRMR if supported */ | ||
403 | if (xprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG) | ||
404 | reader = rdma_read_chunk_frmr; | ||
405 | else | ||
406 | reader = rdma_read_chunk_lcl; | ||
407 | |||
408 | page_no = 0; page_offset = 0; | 392 | page_no = 0; page_offset = 0; |
409 | for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; | 393 | for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; |
410 | ch->rc_discrim != 0; ch++) { | 394 | ch->rc_discrim != 0; ch++) { |
411 | 395 | handle = be32_to_cpu(ch->rc_target.rs_handle); | |
396 | byte_count = be32_to_cpu(ch->rc_target.rs_length); | ||
412 | xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset, | 397 | xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset, |
413 | &rs_offset); | 398 | &rs_offset); |
414 | byte_count = ntohl(ch->rc_target.rs_length); | ||
415 | 399 | ||
416 | while (byte_count > 0) { | 400 | while (byte_count > 0) { |
417 | ret = reader(xprt, rqstp, head, | 401 | last = (ch + 1)->rc_discrim == xdr_zero; |
418 | &page_no, &page_offset, | 402 | ret = xprt->sc_reader(xprt, rqstp, head, |
419 | ntohl(ch->rc_target.rs_handle), | 403 | &page_no, &page_offset, |
420 | byte_count, rs_offset, | 404 | handle, byte_count, |
421 | ((ch+1)->rc_discrim == 0) /* last */ | 405 | rs_offset, last); |
422 | ); | ||
423 | if (ret < 0) | 406 | if (ret < 0) |
424 | goto err; | 407 | goto err; |
425 | byte_count -= ret; | 408 | byte_count -= ret; |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index f2e059bbab42..f609c1c2d38d 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -974,10 +974,12 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) | |||
974 | * NB: iWARP requires remote write access for the data sink | 974 | * NB: iWARP requires remote write access for the data sink |
975 | * of an RDMA_READ. IB does not. | 975 | * of an RDMA_READ. IB does not. |
976 | */ | 976 | */ |
977 | newxprt->sc_reader = rdma_read_chunk_lcl; | ||
977 | if (devattr.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) { | 978 | if (devattr.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) { |
978 | newxprt->sc_frmr_pg_list_len = | 979 | newxprt->sc_frmr_pg_list_len = |
979 | devattr.max_fast_reg_page_list_len; | 980 | devattr.max_fast_reg_page_list_len; |
980 | newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG; | 981 | newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG; |
982 | newxprt->sc_reader = rdma_read_chunk_frmr; | ||
981 | } | 983 | } |
982 | 984 | ||
983 | /* | 985 | /* |