History

svcrdma: Fix backchannel return code

Way back when I was writing the RPC/RDMA server-side backchannel code, I misread the TCP backchannel reply handler logic. When svc_tcp_recvfrom() successfully receives a backchannel reply, it does not return -EAGAIN. It sets XPT_DATA and returns zero. Update svc_rdma_recvfrom() to return zero. Here, XPT_DATA doesn't need to be set again: it is set whenever a new message is received, behind a spin lock in a single threaded context. Also, if handling the cb reply is not successful, the message is simply dropped. There's no special message framing to deal with as there is in the TCP case. Now that the handle_bc_reply() return value is ignored, I've removed the dprintk call sites in the error exit of handle_bc_reply() in favor of trace points in other areas that already report the error cases.

Chuck Lever committed 6 years ago

Commit ea740bd1 parent dbc17ac3 files · +17 −37Browse files

Unified · Split

3 files
  1. include/linux/sunrpc/svc_rdma.h +2 −3
  2. net/sunrpc/xprtrdma/svc_rdma_backchannel.c +10 −28
  3. net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +5 −6
include/linux/sunrpc/svc_rdma.h+2−3
@@ -160,9 +160,8 @@ struct svc_rdma_send_ctxt { · 159 unmodified lines
160};160};
161 161
162/* svc_rdma_backchannel.c */162/* svc_rdma_backchannel.c */
163extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt,163extern void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp,
164 __be32 *rdma_resp,164 struct svc_rdma_recv_ctxt *rctxt);
165 struct xdr_buf *rcvbuf);
166 165
167/* svc_rdma_recvfrom.c */166/* svc_rdma_recvfrom.c */
168extern void svc_rdma_recv_ctxts_destroy(struct svcxprt_rdma *rdma);167extern void svc_rdma_recv_ctxts_destroy(struct svcxprt_rdma *rdma);
net/sunrpc/xprtrdma/svc_rdma_backchannel.c+10−28
@@ -15,26 +15,25 @@ · 14 unmodified lines
15#undef SVCRDMA_BACKCHANNEL_DEBUG15#undef SVCRDMA_BACKCHANNEL_DEBUG
16 16
17/**17/**
18 * svc_rdma_handle_bc_reply - Process incoming backchannel reply18 * svc_rdma_handle_bc_reply - Process incoming backchannel Reply
19 * @xprt: controlling backchannel transport19 * @rqstp: resources for handling the Reply
20 * @rdma_resp: pointer to incoming transport header20 * @rctxt: Received message
21 * @rcvbuf: XDR buffer into which to decode the reply
22 *21 *
23 * Returns:
24 * %0 if @rcvbuf is filled in, xprt_complete_rqst called,
25 * %-EAGAIN if server should call ->recvfrom again.
26 */22 */
27int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp,23void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp,
28 struct xdr_buf *rcvbuf)24 struct svc_rdma_recv_ctxt *rctxt)
29{25{
26 struct svc_xprt *sxprt = rqstp->rq_xprt;
27 struct rpc_xprt *xprt = sxprt->xpt_bc_xprt;
30 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);28 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
29 struct xdr_buf *rcvbuf = &rqstp->rq_arg;
31 struct kvec *dst, *src = &rcvbuf->head[0];30 struct kvec *dst, *src = &rcvbuf->head[0];
31 __be32 *rdma_resp = rctxt->rc_recv_buf;
32 struct rpc_rqst *req;32 struct rpc_rqst *req;
33 u32 credits;33 u32 credits;
34 size_t len;34 size_t len;
35 __be32 xid;35 __be32 xid;
36 __be32 *p;36 __be32 *p;
37 int ret;
38 37
39 p = (__be32 *)src->iov_base;38 p = (__be32 *)src->iov_base;
40 len = src->iov_len;39 len = src->iov_len;
@@ -49,14 +48,10 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, · 8 unmodified lines
49 __func__, (int)len, p);48 __func__, (int)len, p);
50#endif49#endif
51 50
52 ret = -EAGAIN;
53 if (src->iov_len < 24)
54 goto out_shortreply;
55
56 spin_lock(&xprt->queue_lock);51 spin_lock(&xprt->queue_lock);
57 req = xprt_lookup_rqst(xprt, xid);52 req = xprt_lookup_rqst(xprt, xid);
58 if (!req)53 if (!req)
59 goto out_notfound;54 goto out_unlock;
60 55
61 dst = &req->rq_private_buf.head[0];56 dst = &req->rq_private_buf.head[0];
62 memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf));57 memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf));
@@ -77,25 +72,12 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, · 14 unmodified lines
77 spin_unlock(&xprt->transport_lock);72 spin_unlock(&xprt->transport_lock);
78 73
79 spin_lock(&xprt->queue_lock);74 spin_lock(&xprt->queue_lock);
80 ret = 0;
81 xprt_complete_rqst(req->rq_task, rcvbuf->len);75 xprt_complete_rqst(req->rq_task, rcvbuf->len);
82 xprt_unpin_rqst(req);76 xprt_unpin_rqst(req);
83 rcvbuf->len = 0;77 rcvbuf->len = 0;
84 78
85out_unlock:79out_unlock:
86 spin_unlock(&xprt->queue_lock);80 spin_unlock(&xprt->queue_lock);
87out:
88 return ret;
89
90out_shortreply:
91 dprintk("svcrdma: short bc reply: xprt=%p, len=%zu\n",
92 xprt, src->iov_len);
93 goto out;
94
95out_notfound:
96 dprintk("svcrdma: unrecognized bc reply: xprt=%p, xid=%08x\n",
97 xprt, be32_to_cpu(xid));
98 goto out_unlock;
99}81}
100 82
101/* Send a backwards direction RPC call.83/* Send a backwards direction RPC call.
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c+5−6
@@ -878,12 +878,9 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) · 877 unmodified lines
878 goto out_drop;878 goto out_drop;
879 rqstp->rq_xprt_hlen = ret;879 rqstp->rq_xprt_hlen = ret;
880 880
881 if (svc_rdma_is_backchannel_reply(xprt, p)) {881 if (svc_rdma_is_backchannel_reply(xprt, p))
882 ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, p,882 goto out_backchannel;
883 &rqstp->rq_arg);883
884 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);
885 return ret;
886 }
887 svc_rdma_get_inv_rkey(rdma_xprt, ctxt);884 svc_rdma_get_inv_rkey(rdma_xprt, ctxt);
888 885
889 p += rpcrdma_fixed_maxsz;886 p += rpcrdma_fixed_maxsz;
@@ -913,6 +910,8 @@ out_postfail: · 23 unmodified lines
913 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);910 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);
914 return ret;911 return ret;
915 912
913out_backchannel:
914 svc_rdma_handle_bc_reply(rqstp, ctxt);
916out_drop:915out_drop:
917 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);916 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);
918 return 0;917 return 0;