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: Chuck Lever <chuck.lever@oracle.com> Tested-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
4b9c7f9db9
commit
6b26cc8c8e
@ -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
|
* always set csa_cachethis to FALSE because the current implementation
|
||||||
* of the back channel DRC only supports caching the CB_SEQUENCE operation.
|
* 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_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_rqst_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxwrite_overhead;
|
||||||
max_resp_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxread_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);
|
args->fc_attrs.max_ops, args->fc_attrs.max_reqs);
|
||||||
|
|
||||||
/* Back channel attributes */
|
/* Back channel attributes */
|
||||||
args->bc_attrs.max_rqst_sz = PAGE_SIZE;
|
args->bc_attrs.max_rqst_sz = max_bc_payload;
|
||||||
args->bc_attrs.max_resp_sz = PAGE_SIZE;
|
args->bc_attrs.max_resp_sz = max_bc_payload;
|
||||||
args->bc_attrs.max_resp_sz_cached = 0;
|
args->bc_attrs.max_resp_sz_cached = 0;
|
||||||
args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
|
args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
|
||||||
args->bc_attrs.max_reqs = NFS41_BC_MAX_CALLBACKS;
|
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;
|
int status;
|
||||||
|
|
||||||
nfs4_init_channel_attrs(&args);
|
nfs4_init_channel_attrs(&args, clp->cl_rpcclient);
|
||||||
args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
|
args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
|
||||||
|
|
||||||
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||||
|
@ -176,6 +176,7 @@ void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
|
|||||||
int rpc_protocol(struct rpc_clnt *);
|
int rpc_protocol(struct rpc_clnt *);
|
||||||
struct net * rpc_net_ns(struct rpc_clnt *);
|
struct net * rpc_net_ns(struct rpc_clnt *);
|
||||||
size_t rpc_max_payload(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);
|
unsigned long rpc_get_timeout(struct rpc_clnt *clnt);
|
||||||
void rpc_force_rebind(struct rpc_clnt *);
|
void rpc_force_rebind(struct rpc_clnt *);
|
||||||
size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
|
size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
|
||||||
|
@ -142,6 +142,7 @@ struct rpc_xprt_ops {
|
|||||||
int (*bc_setup)(struct rpc_xprt *xprt,
|
int (*bc_setup)(struct rpc_xprt *xprt,
|
||||||
unsigned int min_reqs);
|
unsigned int min_reqs);
|
||||||
int (*bc_up)(struct svc_serv *serv, struct net *net);
|
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_free_rqst)(struct rpc_rqst *rqst);
|
||||||
void (*bc_destroy)(struct rpc_xprt *xprt,
|
void (*bc_destroy)(struct rpc_xprt *xprt,
|
||||||
unsigned int max_reqs);
|
unsigned int max_reqs);
|
||||||
|
@ -1413,6 +1413,23 @@ size_t rpc_max_payload(struct rpc_clnt *clnt)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_max_payload);
|
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
|
* rpc_get_timeout - Get timeout for transport in units of HZ
|
||||||
* @clnt: RPC client to query
|
* @clnt: RPC client to query
|
||||||
|
@ -191,6 +191,22 @@ int xprt_rdma_bc_up(struct svc_serv *serv, struct net *net)
|
|||||||
return 0;
|
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
|
* rpcrdma_bc_marshal_reply - Send backwards direction reply
|
||||||
* @rqst: buffer containing RPC reply data
|
* @rqst: buffer containing RPC reply data
|
||||||
|
@ -707,6 +707,7 @@ static struct rpc_xprt_ops xprt_rdma_procs = {
|
|||||||
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
||||||
.bc_setup = xprt_rdma_bc_setup,
|
.bc_setup = xprt_rdma_bc_setup,
|
||||||
.bc_up = xprt_rdma_bc_up,
|
.bc_up = xprt_rdma_bc_up,
|
||||||
|
.bc_maxpayload = xprt_rdma_bc_maxpayload,
|
||||||
.bc_free_rqst = xprt_rdma_bc_free_rqst,
|
.bc_free_rqst = xprt_rdma_bc_free_rqst,
|
||||||
.bc_destroy = xprt_rdma_bc_destroy,
|
.bc_destroy = xprt_rdma_bc_destroy,
|
||||||
#endif
|
#endif
|
||||||
|
@ -534,6 +534,7 @@ void xprt_rdma_cleanup(void);
|
|||||||
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
||||||
int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int);
|
int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int);
|
||||||
int xprt_rdma_bc_up(struct svc_serv *, struct net *);
|
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);
|
int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int);
|
||||||
void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *);
|
void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *);
|
||||||
int rpcrdma_bc_marshal_reply(struct rpc_rqst *);
|
int rpcrdma_bc_marshal_reply(struct rpc_rqst *);
|
||||||
|
@ -1365,6 +1365,11 @@ static int xs_tcp_bc_up(struct svc_serv *serv, struct net *net)
|
|||||||
return ret;
|
return ret;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t xs_tcp_bc_maxpayload(struct rpc_xprt *xprt)
|
||||||
|
{
|
||||||
|
return PAGE_SIZE;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static inline int _xs_tcp_read_data(struct rpc_xprt *xprt,
|
static inline int _xs_tcp_read_data(struct rpc_xprt *xprt,
|
||||||
struct xdr_skb_reader *desc)
|
struct xdr_skb_reader *desc)
|
||||||
@ -2660,6 +2665,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
|
|||||||
#ifdef CONFIG_SUNRPC_BACKCHANNEL
|
#ifdef CONFIG_SUNRPC_BACKCHANNEL
|
||||||
.bc_setup = xprt_setup_bc,
|
.bc_setup = xprt_setup_bc,
|
||||||
.bc_up = xs_tcp_bc_up,
|
.bc_up = xs_tcp_bc_up,
|
||||||
|
.bc_maxpayload = xs_tcp_bc_maxpayload,
|
||||||
.bc_free_rqst = xprt_free_bc_rqst,
|
.bc_free_rqst = xprt_free_bc_rqst,
|
||||||
.bc_destroy = xprt_destroy_bc,
|
.bc_destroy = xprt_destroy_bc,
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user