Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

svcrdma: Clean up RPC-over-RDMA backchannel reply processing

Replace C structure-based XDR decoding with pointer arithmetic.
Pointer arithmetic is considered more portable.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>

authored by

Chuck Lever and committed by
J. Bruce Fields
f5821c76 4757d90b

+33 -20
+1 -1
include/linux/sunrpc/svc_rdma.h
··· 204 204 205 205 /* svc_rdma_backchannel.c */ 206 206 extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, 207 - struct rpcrdma_msg *rmsgp, 207 + __be32 *rdma_resp, 208 208 struct xdr_buf *rcvbuf); 209 209 210 210 /* svc_rdma_marshal.c */
+14 -4
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
··· 12 12 13 13 #undef SVCRDMA_BACKCHANNEL_DEBUG 14 14 15 - int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, struct rpcrdma_msg *rmsgp, 15 + /** 16 + * svc_rdma_handle_bc_reply - Process incoming backchannel reply 17 + * @xprt: controlling backchannel transport 18 + * @rdma_resp: pointer to incoming transport header 19 + * @rcvbuf: XDR buffer into which to decode the reply 20 + * 21 + * Returns: 22 + * %0 if @rcvbuf is filled in, xprt_complete_rqst called, 23 + * %-EAGAIN if server should call ->recvfrom again. 24 + */ 25 + int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, 16 26 struct xdr_buf *rcvbuf) 17 27 { 18 28 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); ··· 37 27 38 28 p = (__be32 *)src->iov_base; 39 29 len = src->iov_len; 40 - xid = rmsgp->rm_xid; 30 + xid = *rdma_resp; 41 31 42 32 #ifdef SVCRDMA_BACKCHANNEL_DEBUG 43 33 pr_info("%s: xid=%08x, length=%zu\n", 44 34 __func__, be32_to_cpu(xid), len); 45 35 pr_info("%s: RPC/RDMA: %*ph\n", 46 - __func__, (int)RPCRDMA_HDRLEN_MIN, rmsgp); 36 + __func__, (int)RPCRDMA_HDRLEN_MIN, rdma_resp); 47 37 pr_info("%s: RPC: %*ph\n", 48 38 __func__, (int)len, p); 49 39 #endif ··· 63 53 goto out_unlock; 64 54 memcpy(dst->iov_base, p, len); 65 55 66 - credits = be32_to_cpu(rmsgp->rm_credit); 56 + credits = be32_to_cpup(rdma_resp + 2); 67 57 if (credits == 0) 68 58 credits = 1; /* don't deadlock */ 69 59 else if (credits > r_xprt->rx_buf.rb_bc_max_requests)
+18 -15
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
··· 613 613 * the RPC/RDMA header small and fixed in size, so it is 614 614 * straightforward to check the RPC header's direction field. 615 615 */ 616 - static bool 617 - svc_rdma_is_backchannel_reply(struct svc_xprt *xprt, struct rpcrdma_msg *rmsgp) 616 + static bool svc_rdma_is_backchannel_reply(struct svc_xprt *xprt, 617 + __be32 *rdma_resp) 618 618 { 619 - __be32 *p = (__be32 *)rmsgp; 619 + __be32 *p; 620 620 621 621 if (!xprt->xpt_bc_xprt) 622 622 return false; 623 623 624 - if (rmsgp->rm_type != rdma_msg) 625 - return false; 626 - if (rmsgp->rm_body.rm_chunks[0] != xdr_zero) 627 - return false; 628 - if (rmsgp->rm_body.rm_chunks[1] != xdr_zero) 629 - return false; 630 - if (rmsgp->rm_body.rm_chunks[2] != xdr_zero) 624 + p = rdma_resp + 3; 625 + if (*p++ != rdma_msg) 631 626 return false; 632 627 633 - /* sanity */ 634 - if (p[7] != rmsgp->rm_xid) 628 + if (*p++ != xdr_zero) 629 + return false; 630 + if (*p++ != xdr_zero) 631 + return false; 632 + if (*p++ != xdr_zero) 633 + return false; 634 + 635 + /* XID sanity */ 636 + if (*p++ != *rdma_resp) 635 637 return false; 636 638 /* call direction */ 637 - if (p[8] == cpu_to_be32(RPC_CALL)) 639 + if (*p == cpu_to_be32(RPC_CALL)) 638 640 return false; 639 641 640 642 return true; ··· 702 700 goto out_drop; 703 701 rqstp->rq_xprt_hlen = ret; 704 702 705 - if (svc_rdma_is_backchannel_reply(xprt, rmsgp)) { 706 - ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, rmsgp, 703 + if (svc_rdma_is_backchannel_reply(xprt, &rmsgp->rm_xid)) { 704 + ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, 705 + &rmsgp->rm_xid, 707 706 &rqstp->rq_arg); 708 707 svc_rdma_put_context(ctxt, 0); 709 708 if (ret)