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:
Chuck Lever 2016-05-02 14:40:40 -04:00 committed by Anna Schumaker
parent 4b9c7f9db9
commit 6b26cc8c8e
8 changed files with 49 additions and 4 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 *);

View File

@ -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