git: 77535f91f623 - main - nfscl: Yet more fixes for the NFS over RDMA client glue

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Mon, 14 Sep 2026 00:14:38 UTC
The branch main has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=77535f91f623ec5bda9d45de878165cb6b3cdba1

commit 77535f91f623ec5bda9d45de878165cb6b3cdba1
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2026-09-14 00:12:46 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2026-09-14 00:12:46 +0000

    nfscl: Yet more fixes for the NFS over RDMA client glue
    
    Yet again.  I was trying to make the svc_vc_backchannel()
    operations do double duty and be used by the clnt_rdma.c code
    as well.  It got too messy, so this reverts svc_vc.c back to
    its pre-glue form and adds the small changes needed to support
    a separate set of svc_rdma_backchannel_xxx() functions.
    
    This commit should not affect non-RDMA behaviour.
    
    MFC after:      3 months
    Fixes:  884ee8d6c9b4 ("nfscl: Add some glue for client side NFS over RDMA")
---
 sys/fs/nfs/nfs_commonkrpc.c | 19 ++++++++++++-------
 sys/rpc/clnt_rc.c           |  2 +-
 sys/rpc/krpc.h              |  5 ++---
 sys/rpc/svc.h               |  1 +
 sys/rpc/svc_vc.c            | 12 ++----------
 5 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index 415bba961716..160329968fa2 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -492,11 +492,10 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
 			CLNT_CONTROL(client, CLSET_TLS, &one);
 	} else {
 		/* RDMA. */
-		if (NFSHASNFSV4N(nmp) && cred != NULL) {
+		if (NFSHASNFSV4N(nmp) && cred != NULL &&
+		    svc_rdma_create_backchannel_call != NULL) {
 			/*
-			 * Set up the backchannel. svc_vc_create_backchannel()
-			 * is sufficient.  The rdma boolean in conn_cf will get
-			 * set by the CLSET_BACKCHANNEL control.
+			 * Set up the backchannel.
 			 */
 			/*
 			 * Make sure the nfscbd_pool doesn't get
@@ -506,7 +505,8 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
 			if (nfs_numnfscbd > 0) {
 				nfs_numnfscbd++;
 				NFSD_UNLOCK();
-				xprt = svc_vc_create_backchannel(nfscbd_pool);
+				xprt = svc_rdma_create_backchannel_call(
+				    nfscbd_pool);
 				CLNT_CONTROL(client, CLSET_BACKCHANNEL, xprt);
 				NFSD_LOCK();
 				nfs_numnfscbd--;
@@ -734,7 +734,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
 	struct ucred *authcred, *savcred;
 	struct nfsclsession *sep;
 	uint8_t sessionid[NFSX_V4SESSIONID];
-	bool nextconn_set;
+	bool nextconn_set, has_mreduce;
 	struct timespec trylater_delay, ts, waituntil;
 
 	/* Initially 1msec. */
@@ -749,6 +749,10 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
 		return (ESTALE);
 	}
 
+	has_mreduce = false;
+	if (nmp != NULL && NFSHASRDMA(nmp) &&
+	    (nd->nd_mreq->m_flags & M_PROTO11) != 0)
+		has_mreduce = true;
 	/*
 	 * Set authcred, which is used to acquire RPC credentials to
 	 * the cred argument, by default. The crhold() should not be
@@ -1536,7 +1540,8 @@ out:
 	}
 #endif
 
-	rpc_remove_mreduce(nd->nd_mreq, false);	/* Will be free'd by caller. */
+	if (has_mreduce)
+		rpc_remove_mreduce(nd->nd_mreq, false);
 	m_freem(nd->nd_mreq);
 	if (usegssname == 0)
 		AUTH_DESTROY(auth);
diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c
index c19b3e5eefc8..9094c9d9ee14 100644
--- a/sys/rpc/clnt_rc.c
+++ b/sys/rpc/clnt_rc.c
@@ -51,7 +51,7 @@
 
 xprt_rdma_check_route_ftype *rdma_check_route = NULL;
 clnt_rdma_create_ftype *clnt_rdma_create_call = NULL;
-clnt_rdma_bcksend_ftype *clnt_rdma_bcksend_call = NULL;
+svc_rdma_create_backchannel_ftype *svc_rdma_create_backchannel_call = NULL;
 
 static enum clnt_stat clnt_reconnect_call(CLIENT *, struct rpc_callextra *,
     rpcproc_t, struct mbuf *, struct mbuf **, struct timeval);
diff --git a/sys/rpc/krpc.h b/sys/rpc/krpc.h
index e0dea323d190..bfeee008a65c 100644
--- a/sys/rpc/krpc.h
+++ b/sys/rpc/krpc.h
@@ -51,8 +51,8 @@ typedef int	xprt_rdma_check_route_ftype(struct vnet *vnet,
 		    struct sockaddr *dstaddr, uint32_t cbslots);
 extern xprt_rdma_check_route_ftype *rdma_check_route;
 
-typedef bool_t	clnt_rdma_bcksend_ftype(SVCXPRT *xprt, struct mbuf *m);
-extern clnt_rdma_bcksend_ftype *clnt_rdma_bcksend_call;
+typedef SVCXPRT *svc_rdma_create_backchannel_ftype(SVCPOOL *nfscbdool);
+extern svc_rdma_create_backchannel_ftype *svc_rdma_create_backchannel_call;
 
 typedef CLIENT	*clnt_rdma_create_ftype(struct sockaddr *raddr,
 		    const rpcprog_t prog, const rpcvers_t vers, int intrflag,
@@ -153,7 +153,6 @@ struct cf_conn {  /* kept in xprt->xp_p1 for actual connection */
 	struct mbuf *mreq;	/* current record being built from mpending */
 	uint32_t resid;		/* number of bytes needed for fragment */
 	bool_t eor;		/* reading last fragment of current record */
-	bool_t rdma;		/* On an RDMA connection. */
 };
 
 void rpcnl_init(void);
diff --git a/sys/rpc/svc.h b/sys/rpc/svc.h
index 537dad0fdb65..f247b962c927 100644
--- a/sys/rpc/svc.h
+++ b/sys/rpc/svc.h
@@ -617,6 +617,7 @@ extern SVCXPRT *svc_vc_create(SVCPOOL *, struct socket *,
          */
 
 extern SVCXPRT *svc_vc_create_backchannel(SVCPOOL *);
+extern SVCXPRT *svc_rdma_create_backchannel(SVCPOOL *);
 
 extern void *clnt_bck_create(struct socket *, const rpcprog_t, const rpcvers_t);
 	/*
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c
index 49a58b567e8f..24c09f182174 100644
--- a/sys/rpc/svc_vc.c
+++ b/sys/rpc/svc_vc.c
@@ -1063,7 +1063,6 @@ svc_vc_backchannel_reply(SVCXPRT *xprt, struct rpc_msg *msg,
     struct sockaddr *addr, struct mbuf *m, uint32_t *seq)
 {
 	struct ct_data *ct;
-	struct cf_conn *cd = (struct cf_conn *)xprt->xp_p1;
 	XDR xdrs;
 	struct mbuf *mrep;
 	bool_t stat = TRUE;
@@ -1076,8 +1075,7 @@ svc_vc_backchannel_reply(SVCXPRT *xprt, struct rpc_msg *msg,
 	 * Leave space for record mark.
 	 */
 	mrep = m_gethdr(M_WAITOK, MT_DATA);
-	if (!cd->rdma)
-		mrep->m_data += sizeof(uint32_t);
+	mrep->m_data += sizeof(uint32_t);
 
 	xdrmbuf_create(&xdrs, mrep, XDR_ENCODE);
 
@@ -1091,13 +1089,7 @@ svc_vc_backchannel_reply(SVCXPRT *xprt, struct rpc_msg *msg,
 		stat = xdr_replymsg(&xdrs, msg);
 	}
 
-	if (stat && cd->rdma) {
-		KASSERT(clnt_rdma_bcksend_call != NULL,
-		    ("svc_vc_backchannel_reply: RDMA set, but "
-		    "clnt_rdma_bcksend_call NULL"));
-
-		stat = clnt_rdma_bcksend_call(xprt, mrep);
-	} else if (stat) {
+	if (stat) {
 		m_fixhdr(mrep);
 
 		/*