Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b26cc8c authored by Chuck Lever's avatar Chuck Lever Committed by Anna Schumaker
Browse files

sunrpc: Advertise maximum backchannel payload size



RPC-over-RDMA transports have a limit on how large a backward
direction (backchannel) RPC message can be. Ensure that the NFSv4.x
CREATE_SESSION operation advertises this limit to servers.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Tested-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 4b9c7f9d
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -7371,9 +7371,11 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
 * always set csa_cachethis to FALSE because the current implementation
 * of the back channel DRC only supports caching the CB_SEQUENCE operation.
 */
static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args,
				    struct rpc_clnt *clnt)
{
	unsigned int max_rqst_sz, max_resp_sz;
	unsigned int max_bc_payload = rpc_max_bc_payload(clnt);

	max_rqst_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxwrite_overhead;
	max_resp_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxread_overhead;
@@ -7391,8 +7393,8 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
		args->fc_attrs.max_ops, args->fc_attrs.max_reqs);

	/* Back channel attributes */
	args->bc_attrs.max_rqst_sz = PAGE_SIZE;
	args->bc_attrs.max_resp_sz = PAGE_SIZE;
	args->bc_attrs.max_rqst_sz = max_bc_payload;
	args->bc_attrs.max_resp_sz = max_bc_payload;
	args->bc_attrs.max_resp_sz_cached = 0;
	args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
	args->bc_attrs.max_reqs = NFS41_BC_MAX_CALLBACKS;
@@ -7496,7 +7498,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp,
	};
	int status;

	nfs4_init_channel_attrs(&args);
	nfs4_init_channel_attrs(&args, clp->cl_rpcclient);
	args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);

	status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+1 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
int		rpc_protocol(struct rpc_clnt *);
struct net *	rpc_net_ns(struct rpc_clnt *);
size_t		rpc_max_payload(struct rpc_clnt *);
size_t		rpc_max_bc_payload(struct rpc_clnt *);
unsigned long	rpc_get_timeout(struct rpc_clnt *clnt);
void		rpc_force_rebind(struct rpc_clnt *);
size_t		rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
+1 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ struct rpc_xprt_ops {
	int		(*bc_setup)(struct rpc_xprt *xprt,
				    unsigned int min_reqs);
	int		(*bc_up)(struct svc_serv *serv, struct net *net);
	size_t		(*bc_maxpayload)(struct rpc_xprt *xprt);
	void		(*bc_free_rqst)(struct rpc_rqst *rqst);
	void		(*bc_destroy)(struct rpc_xprt *xprt,
				      unsigned int max_reqs);
+17 −0
Original line number Diff line number Diff line
@@ -1413,6 +1413,23 @@ size_t rpc_max_payload(struct rpc_clnt *clnt)
}
EXPORT_SYMBOL_GPL(rpc_max_payload);

/**
 * rpc_max_bc_payload - Get maximum backchannel payload size, in bytes
 * @clnt: RPC client to query
 */
size_t rpc_max_bc_payload(struct rpc_clnt *clnt)
{
	struct rpc_xprt *xprt;
	size_t ret;

	rcu_read_lock();
	xprt = rcu_dereference(clnt->cl_xprt);
	ret = xprt->ops->bc_maxpayload(xprt);
	rcu_read_unlock();
	return ret;
}
EXPORT_SYMBOL_GPL(rpc_max_bc_payload);

/**
 * rpc_get_timeout - Get timeout for transport in units of HZ
 * @clnt: RPC client to query
+16 −0
Original line number Diff line number Diff line
@@ -191,6 +191,22 @@ int xprt_rdma_bc_up(struct svc_serv *serv, struct net *net)
	return 0;
}

/**
 * xprt_rdma_bc_maxpayload - Return maximum backchannel message size
 * @xprt: transport
 *
 * Returns maximum size, in bytes, of a backchannel message
 */
size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *xprt)
{
	struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
	struct rpcrdma_create_data_internal *cdata = &r_xprt->rx_data;
	size_t maxmsg;

	maxmsg = min_t(unsigned int, cdata->inline_rsize, cdata->inline_wsize);
	return maxmsg - RPCRDMA_HDRLEN_MIN;
}

/**
 * rpcrdma_bc_marshal_reply - Send backwards direction reply
 * @rqst: buffer containing RPC reply data
Loading