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
160160 };
161161
162162 /* svc_rdma_backchannel.c */
163−extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt,
164− __be32 *rdma_resp,
165− struct xdr_buf *rcvbuf);
163+extern void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp,
164+ struct svc_rdma_recv_ctxt *rctxt);
166165
167166 /* svc_rdma_recvfrom.c */
168167 extern 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
1515 #undef SVCRDMA_BACKCHANNEL_DEBUG
1616
1717 /**
18− * svc_rdma_handle_bc_reply - Process incoming backchannel reply
19− * @xprt: controlling backchannel transport
20− * @rdma_resp: pointer to incoming transport header
21− * @rcvbuf: XDR buffer into which to decode the reply
18+ * svc_rdma_handle_bc_reply - Process incoming backchannel Reply
19+ * @rqstp: resources for handling the Reply
20+ * @rctxt: Received message
2221 *
23− * Returns:
24− * %0 if @rcvbuf is filled in, xprt_complete_rqst called,
25− * %-EAGAIN if server should call ->recvfrom again.
2622 */
27−int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp,
28− struct xdr_buf *rcvbuf)
23+void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp,
24+ struct svc_rdma_recv_ctxt *rctxt)
2925 {
26+ struct svc_xprt *sxprt = rqstp->rq_xprt;
27+ struct rpc_xprt *xprt = sxprt->xpt_bc_xprt;
3028 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
29+ struct xdr_buf *rcvbuf = &rqstp->rq_arg;
3130 struct kvec *dst, *src = &rcvbuf->head[0];
31+ __be32 *rdma_resp = rctxt->rc_recv_buf;
3232 struct rpc_rqst *req;
3333 u32 credits;
3434 size_t len;
3535 __be32 xid;
3636 __be32 *p;
37− int ret;
3837
3938 p = (__be32 *)src->iov_base;
4039 len = src->iov_len;
@@ -49,14 +48,10 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, · 8 unmodified lines
4948 __func__, (int)len, p);
5049 #endif
5150
52− ret = -EAGAIN;
53− if (src->iov_len < 24)
54− goto out_shortreply;
55−
5651 spin_lock(&xprt->queue_lock);
5752 req = xprt_lookup_rqst(xprt, xid);
5853 if (!req)
59− goto out_notfound;
54+ goto out_unlock;
6055
6156 dst = &req->rq_private_buf.head[0];
6257 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
7772 spin_unlock(&xprt->transport_lock);
7873
7974 spin_lock(&xprt->queue_lock);
80− ret = 0;
8175 xprt_complete_rqst(req->rq_task, rcvbuf->len);
8276 xprt_unpin_rqst(req);
8377 rcvbuf->len = 0;
8478
8579 out_unlock:
8680 spin_unlock(&xprt->queue_lock);
87−out:
88− return ret;
89−
90−out_shortreply:
91− dprintk("svcrdma: short bc reply: xprt=%p, len=%zu\n",
92− xprt, src->iov_len);
93− goto out;
94−
95−out_notfound:
96− dprintk("svcrdma: unrecognized bc reply: xprt=%p, xid=%08x\n",
97− xprt, be32_to_cpu(xid));
98− goto out_unlock;
9981 }
10082
10183 /* 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
878878 goto out_drop;
879879 rqstp->rq_xprt_hlen = ret;
880880
881− if (svc_rdma_is_backchannel_reply(xprt, p)) {
882− ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, p,
883− &rqstp->rq_arg);
884− svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);
885− return ret;
886− }
881+ if (svc_rdma_is_backchannel_reply(xprt, p))
882+ goto out_backchannel;
883+
887884 svc_rdma_get_inv_rkey(rdma_xprt, ctxt);
888885
889886 p += rpcrdma_fixed_maxsz;
@@ -913,6 +910,8 @@ out_postfail: · 23 unmodified lines
913910 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);
914911 return ret;
915912
913+out_backchannel:
914+ svc_rdma_handle_bc_reply(rqstp, ctxt);
916915 out_drop:
917916 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);
918917 return 0;