From: Tom Wu <tomwu@nvidia.com>
Subject: [PATCH] BACKPORT: net/sunrpc/xprtrdma/svc_rdma_transport.c

Change-Id: If4604989166298ec3f97f6f9a4a0630149f9b614
Signed-off-by: Tom Wu <tomwu@nvidia.com>
---
 net/sunrpc/xprtrdma/svc_rdma_transport.c | 104 ++++++++++++++++++++++-
 1 file changed, 103 insertions(+), 1 deletion(-)

--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -59,7 +59,9 @@
 #include <linux/sunrpc/svc_rdma.h>
 
 #include "xprt_rdma.h"
+#ifdef HAVE_TRACE_RPCRDMA_H
 #include <trace/events/rpcrdma.h>
+#endif
 
 #define RPCDBG_FACILITY	RPCDBG_SVCXPRT
 
@@ -70,21 +72,52 @@ static struct svc_xprt *svc_rdma_create(
 					struct sockaddr *sa, int salen,
 					int flags);
 static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt);
+#if !defined(HAVE_SVC_RDMA_RELEASE_RQST) && !defined(HAVE_XPO_RELEASE_CTXT)
+static void svc_rdma_release_rqst(struct svc_rqst *);
+#endif
 static void svc_rdma_detach(struct svc_xprt *xprt);
 static void svc_rdma_free(struct svc_xprt *xprt);
 static int svc_rdma_has_wspace(struct svc_xprt *xprt);
+#ifdef HAVE_SVC_XPRT_XPO_SECURE_PORT
+#ifdef HAVE_XPO_SECURE_PORT_NO_RETURN
+static void svc_rdma_secure_port(struct svc_rqst *);
+#else
+static int svc_rdma_secure_port(struct svc_rqst *);
+#endif
+#endif
 static void svc_rdma_kill_temp_xprt(struct svc_xprt *);
 
+#ifdef HAVE_SVC_XPRT_XPO_PREP_REPLY_HDR
+static void svc_rdma_prep_reply_hdr(struct svc_rqst *rqstp)
+{
+}
+#endif
+
 static const struct svc_xprt_ops svc_rdma_ops = {
 	.xpo_create = svc_rdma_create,
 	.xpo_recvfrom = svc_rdma_recvfrom,
 	.xpo_sendto = svc_rdma_sendto,
+#ifdef HAVE_XPO_READ_PAYLOAD
+	.xpo_read_payload = svc_rdma_read_payload,
+#endif
+#ifdef HAVE_XPO_RESULT_PAYLOAD
 	.xpo_result_payload = svc_rdma_result_payload,
+#endif
+#ifdef HAVE_XPO_RELEASE_CTXT
 	.xpo_release_ctxt = svc_rdma_release_ctxt,
+#else
+	.xpo_release_rqst = svc_rdma_release_rqst,
+#endif
 	.xpo_detach = svc_rdma_detach,
 	.xpo_free = svc_rdma_free,
+#ifdef HAVE_SVC_XPRT_XPO_PREP_REPLY_HDR
+	.xpo_prep_reply_hdr = svc_rdma_prep_reply_hdr,
+#endif
 	.xpo_has_wspace = svc_rdma_has_wspace,
 	.xpo_accept = svc_rdma_accept,
+#ifdef HAVE_SVC_XPRT_XPO_SECURE_PORT
+	.xpo_secure_port = svc_rdma_secure_port,
+#endif
 	.xpo_kill_temp_xprt = svc_rdma_kill_temp_xprt,
 };
 
@@ -96,12 +129,35 @@ struct svc_xprt_class svc_rdma_class = {
 	.xcl_ident = XPRT_TRANSPORT_RDMA,
 };
 
+#if defined(CONFIG_SUNRPC_BACKCHANNEL) && defined(HAVE_RPC_XPRT_OPS_BC_UP)
+static const struct svc_xprt_ops svc_rdma_bc_ops = {
+    .xpo_create = svc_rdma_create,
+    .xpo_detach = svc_rdma_detach,
+    .xpo_free = svc_rdma_free,
+#ifdef HAVE_SVC_XPRT_XPO_PREP_REPLY_HDR
+    .xpo_prep_reply_hdr = svc_rdma_prep_reply_hdr,
+#endif
+#ifdef HAVE_SVC_XPRT_XPO_SECURE_PORT
+    .xpo_secure_port = svc_rdma_secure_port,
+#endif
+};
+
+struct svc_xprt_class svc_rdma_bc_class = {
+    .xcl_name = "rdma-bc",
+    .xcl_owner = THIS_MODULE,
+    .xcl_ops = &svc_rdma_bc_ops,
+    .xcl_max_payload = (1024 - RPCRDMA_HDRLEN_MIN)
+};
+#endif
+
 /* QP event handler */
 static void qp_event_handler(struct ib_event *event, void *context)
 {
 	struct svc_xprt *xprt = context;
 
+#ifdef HAVE_TRACE_RPCRDMA_H
 	trace_svcrdma_qp_error(event, (struct sockaddr *)&xprt->xpt_remote);
+#endif
 	switch (event->event) {
 	/* These are considered benign events */
 	case IB_EVENT_PATH_MIG:
@@ -117,7 +173,12 @@ static void qp_event_handler(struct ib_e
 	case IB_EVENT_QP_ACCESS_ERR:
 	case IB_EVENT_DEVICE_FATAL:
 	default:
+#ifdef HAVE_SVC_XPRT_DEFERRED_CLOSE
 		svc_xprt_deferred_close(xprt);
+#else
+		set_bit(XPT_CLOSE, &xprt->xpt_flags);
+		svc_xprt_enqueue(xprt);
+#endif
 		break;
 	}
 }
@@ -289,7 +350,12 @@ static int svc_rdma_cma_handler(struct r
 		break;
 	case RDMA_CM_EVENT_DISCONNECTED:
 	case RDMA_CM_EVENT_DEVICE_REMOVAL:
+#ifdef HAVE_SVC_XPRT_DEFERRED_CLOSE
 		svc_xprt_deferred_close(xprt);
+#else
+		set_bit(XPT_CLOSE, &xprt->xpt_flags);
+		svc_xprt_enqueue(xprt);
+#endif
 		break;
 	default:
 		break;
@@ -401,7 +467,6 @@ static struct svc_xprt *svc_rdma_accept(
 	newxprt->sc_max_req_size = svcrdma_max_req_size;
 	newxprt->sc_max_requests = svcrdma_max_requests;
 	newxprt->sc_max_bc_requests = svcrdma_max_bc_requests;
-	newxprt->sc_recv_batch = RPCRDMA_MAX_RECV_BATCH;
 	newxprt->sc_fc_credits = cpu_to_be32(newxprt->sc_max_requests);
 
 	/* Qualify the transport's resource defaults with the
@@ -414,11 +479,18 @@ static struct svc_xprt *svc_rdma_accept(
 	newxprt->sc_max_send_sges += (svcrdma_max_req_size / PAGE_SIZE) + 1;
 	if (newxprt->sc_max_send_sges > dev->attrs.max_send_sge)
 		newxprt->sc_max_send_sges = dev->attrs.max_send_sge;
+#ifdef HAVE_SVCXPRT_RDMA_SC_PENDING_RECVS
+	newxprt->sc_recv_batch = RPCRDMA_MAX_RECV_BATCH;
 	rq_depth = newxprt->sc_max_requests + newxprt->sc_max_bc_requests +
 		   newxprt->sc_recv_batch + 1 /* drain */;
+#else
+	rq_depth = newxprt->sc_max_requests + newxprt->sc_max_bc_requests;
+#endif
 	if (rq_depth > dev->attrs.max_qp_wr) {
 		rq_depth = dev->attrs.max_qp_wr;
+#ifdef HAVE_SVCXPRT_RDMA_SC_PENDING_RECVS
 		newxprt->sc_recv_batch = 1;
+#endif
 		newxprt->sc_max_requests = rq_depth - 2;
 		newxprt->sc_max_bc_requests = 2;
 	}
@@ -436,7 +508,9 @@ static struct svc_xprt *svc_rdma_accept(
 
 	newxprt->sc_pd = ib_alloc_pd(dev, 0);
 	if (IS_ERR(newxprt->sc_pd)) {
+#ifdef HAVE_TRACE_RPCRDMA_H
 		trace_svcrdma_pd_err(newxprt, PTR_ERR(newxprt->sc_pd));
+#endif
 		goto errout;
 	}
 	newxprt->sc_sq_cq = ib_alloc_cq_any(dev, newxprt, newxprt->sc_sq_depth,
@@ -469,7 +543,9 @@ static struct svc_xprt *svc_rdma_accept(
 		newxprt->sc_sq_depth, rq_depth);
 	ret = rdma_create_qp(newxprt->sc_cm_id, newxprt->sc_pd, &qp_attr);
 	if (ret) {
+#ifdef HAVE_TRACE_RPCRDMA_H
 		trace_svcrdma_qp_err(newxprt, ret);
+#endif
 		goto errout;
 	}
 	newxprt->sc_max_send_sges = qp_attr.cap.max_send_sge;
@@ -479,7 +555,9 @@ static struct svc_xprt *svc_rdma_accept(
 		newxprt->sc_snd_w_inv = false;
 	if (!rdma_protocol_iwarp(dev, newxprt->sc_port_num) &&
 	    !rdma_ib_or_roce(dev, newxprt->sc_port_num)) {
+#ifdef HAVE_TRACE_RPCRDMA_H
 		trace_svcrdma_fabric_err(newxprt, -EINVAL);
+#endif
 		goto errout;
 	}
 
@@ -501,7 +579,9 @@ static struct svc_xprt *svc_rdma_accept(
 					   dev->attrs.max_qp_init_rd_atom);
 	if (!conn_param.initiator_depth) {
 		ret = -EINVAL;
+#ifdef HAVE_TRACE_RPCRDMA_H
 		trace_svcrdma_initdepth_err(newxprt, ret);
+#endif
 		goto errout;
 	}
 	conn_param.private_data = &pmsg;
@@ -511,7 +591,9 @@ static struct svc_xprt *svc_rdma_accept(
 	ret = rdma_accept(newxprt->sc_cm_id, &conn_param);
 	rdma_unlock_handler(newxprt->sc_cm_id);
 	if (ret) {
+#ifdef HAVE_TRACE_RPCRDMA_H
 		trace_svcrdma_accept_err(newxprt, ret);
+#endif
 		goto errout;
 	}
 
@@ -541,6 +623,12 @@ static struct svc_xprt *svc_rdma_accept(
 	return NULL;
 }
 
+#if !defined(HAVE_SVC_RDMA_RELEASE_RQST) && !defined(HAVE_XPO_RELEASE_CTXT)
+static void svc_rdma_release_rqst(struct svc_rqst *rqstp)
+{
+}
+#endif
+
 static void svc_rdma_detach(struct svc_xprt *xprt)
 {
 	struct svcxprt_rdma *rdma =
@@ -609,6 +697,20 @@ static int svc_rdma_has_wspace(struct sv
 	return 1;
 }
 
+#ifdef HAVE_SVC_XPRT_XPO_SECURE_PORT
+#ifdef HAVE_XPO_SECURE_PORT_NO_RETURN
+static void svc_rdma_secure_port(struct svc_rqst *rqstp)
+{
+	set_bit(RQ_SECURE, &rqstp->rq_flags);
+}
+#else
+static int svc_rdma_secure_port(struct svc_rqst *rqstp)
+{
+   return 1;
+}
+#endif
+#endif
+
 static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt)
 {
 }
