xprtrdma: Split xprt_rdma_send_request
authorChuck Lever <chuck.lever@oracle.com>
Fri, 15 Dec 2017 01:57:31 +0000 (20:57 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Tue, 16 Jan 2018 16:19:48 +0000 (11:19 -0500)
Clean up. @rqst is set up differently for backchannel Replies. For
example, rqst->rq_task and task->tk_client are both NULL. So it is
easier to understand and maintain this code path if it is separated.

Also, we can get rid of the confusing rl_connect_cookie hack in
rpcrdma_bc_receive_call.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
net/sunrpc/xprtrdma/backchannel.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtrdma/xprt_rdma.h

index 11fb38f4d70d32e2b819b5b097bf8f8c8ccb6c3f..6c66a4f855075062648b8cdbc7014b6cfbc12ddd 100644 (file)
@@ -187,13 +187,7 @@ size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *xprt)
        return maxmsg - RPCRDMA_HDRLEN_MIN;
 }
 
-/**
- * rpcrdma_bc_marshal_reply - Send backwards direction reply
- * @rqst: buffer containing RPC reply data
- *
- * Returns zero on success.
- */
-int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst)
+static int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst)
 {
        struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt);
        struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
@@ -220,6 +214,43 @@ int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst)
        return 0;
 }
 
+/**
+ * xprt_rdma_bc_send_reply - marshal and send a backchannel reply
+ * @rqst: RPC rqst with a backchannel RPC reply in rq_snd_buf
+ *
+ * Caller holds the transport's write lock.
+ *
+ * Returns:
+ *     %0 if the RPC message has been sent
+ *     %-ENOTCONN if the caller should reconnect and call again
+ *     %-EIO if a permanent error occurred and the request was not
+ *             sent. Do not try to send this message again.
+ */
+int xprt_rdma_bc_send_reply(struct rpc_rqst *rqst)
+{
+       struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt);
+       struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
+       int rc;
+
+       if (!xprt_connected(rqst->rq_xprt))
+               goto drop_connection;
+
+       rc = rpcrdma_bc_marshal_reply(rqst);
+       if (rc < 0)
+               goto failed_marshal;
+
+       if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req))
+               goto drop_connection;
+       return 0;
+
+failed_marshal:
+       if (rc != -ENOTCONN)
+               return rc;
+drop_connection:
+       xprt_disconnect_done(rqst->rq_xprt);
+       return -ENOTCONN;
+}
+
 /**
  * xprt_rdma_bc_destroy - Release resources for handling backchannel requests
  * @xprt: transport associated with these backchannel resources
@@ -330,9 +361,6 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt,
                __func__, rep, req);
        req->rl_reply = rep;
 
-       /* Defeat the retransmit detection logic in send_request */
-       req->rl_connect_cookie = 0;
-
        /* Queue rqst for ULP's callback service */
        bc_serv = xprt->bc_serv;
        spin_lock(&bc_serv->sv_cb_lock);
index dd7c0aab7535dde934ec9d7f5f56e779698371ab..9207aeacd2c3e1603882e466c22c39d38613df8b 100644 (file)
@@ -754,11 +754,6 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
        __be32 *p;
        int ret;
 
-#if defined(CONFIG_SUNRPC_BACKCHANNEL)
-       if (test_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state))
-               return rpcrdma_bc_marshal_reply(rqst);
-#endif
-
        rpcrdma_set_xdrlen(&req->rl_hdrbuf, 0);
        xdr_init_encode(xdr, &req->rl_hdrbuf,
                        req->rl_rdmabuf->rg_base);
index d0cd6d411b64d2070c0a1d2b6740a01a7e895fed..be8c4e62d3f2b1f88850aae8476fa7f026dab6b3 100644 (file)
@@ -699,22 +699,12 @@ xprt_rdma_free(struct rpc_task *task)
  *
  * Caller holds the transport's write lock.
  *
- * Return values:
- *        0:   The request has been sent
- * ENOTCONN:   Caller needs to invoke connect logic then call again
- *  ENOBUFS:   Call again later to send the request
- *      EIO:   A permanent error occurred. The request was not sent,
- *             and don't try it again
- *
- * send_request invokes the meat of RPC RDMA. It must do the following:
- *
- *  1.  Marshal the RPC request into an RPC RDMA request, which means
- *     putting a header in front of data, and creating IOVs for RDMA
- *     from those in the request.
- *  2.  In marshaling, detect opportunities for RDMA, and use them.
- *  3.  Post a recv message to set up asynch completion, then send
- *     the request (rpcrdma_ep_post).
- *  4.  No partial sends are possible in the RPC-RDMA protocol (as in UDP).
+ * Returns:
+ *     %0 if the RPC message has been sent
+ *     %-ENOTCONN if the caller should reconnect and call again
+ *     %-ENOBUFS if the caller should call again later
+ *     %-EIO if a permanent error occurred and the request was not
+ *             sent. Do not try to send this message again.
  */
 static int
 xprt_rdma_send_request(struct rpc_task *task)
@@ -725,6 +715,11 @@ xprt_rdma_send_request(struct rpc_task *task)
        struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
        int rc = 0;
 
+#if defined(CONFIG_SUNRPC_BACKCHANNEL)
+       if (unlikely(!rqst->rq_buffer))
+               return xprt_rdma_bc_send_reply(rqst);
+#endif /* CONFIG_SUNRPC_BACKCHANNEL */
+
        if (!xprt_connected(xprt))
                goto drop_connection;
 
index ed7e51304bc276e2041dec69adf19662b0ba0929..e084130d3d843edb3a3e300d9f88a078ba513d3c 100644 (file)
@@ -666,7 +666,7 @@ int xprt_rdma_bc_up(struct svc_serv *, struct net *);
 size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *);
 int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int);
 void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *);
-int rpcrdma_bc_marshal_reply(struct rpc_rqst *);
+int xprt_rdma_bc_send_reply(struct rpc_rqst *rqst);
 void xprt_rdma_bc_free_rqst(struct rpc_rqst *);
 void xprt_rdma_bc_destroy(struct rpc_xprt *, unsigned int);
 #endif /* CONFIG_SUNRPC_BACKCHANNEL */