SUNRPC: Add support for per-client timeout values
In order to be able to support setting the timeo and retrans parameters on a per-mountpoint basis, we move the rpc_timeout structure into the rpc_clnt. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
2881ae74e6
commit
ba7392bb37
|
@ -46,6 +46,7 @@ struct rpc_clnt {
|
||||||
cl_autobind : 1;/* use getport() */
|
cl_autobind : 1;/* use getport() */
|
||||||
|
|
||||||
struct rpc_rtt * cl_rtt; /* RTO estimator data */
|
struct rpc_rtt * cl_rtt; /* RTO estimator data */
|
||||||
|
const struct rpc_timeout *cl_timeout; /* Timeout strategy */
|
||||||
|
|
||||||
int cl_nodelen; /* nodename length */
|
int cl_nodelen; /* nodename length */
|
||||||
char cl_nodename[UNX_MAXNODENAME];
|
char cl_nodename[UNX_MAXNODENAME];
|
||||||
|
@ -54,6 +55,7 @@ struct rpc_clnt {
|
||||||
struct dentry * cl_dentry; /* inode */
|
struct dentry * cl_dentry; /* inode */
|
||||||
struct rpc_clnt * cl_parent; /* Points to parent of clones */
|
struct rpc_clnt * cl_parent; /* Points to parent of clones */
|
||||||
struct rpc_rtt cl_rtt_default;
|
struct rpc_rtt cl_rtt_default;
|
||||||
|
struct rpc_timeout cl_timeout_default;
|
||||||
struct rpc_program * cl_program;
|
struct rpc_program * cl_program;
|
||||||
char cl_inline_name[32];
|
char cl_inline_name[32];
|
||||||
};
|
};
|
||||||
|
@ -99,7 +101,7 @@ struct rpc_create_args {
|
||||||
struct sockaddr *address;
|
struct sockaddr *address;
|
||||||
size_t addrsize;
|
size_t addrsize;
|
||||||
struct sockaddr *saddress;
|
struct sockaddr *saddress;
|
||||||
struct rpc_timeout *timeout;
|
const struct rpc_timeout *timeout;
|
||||||
char *servername;
|
char *servername;
|
||||||
struct rpc_program *program;
|
struct rpc_program *program;
|
||||||
u32 version;
|
u32 version;
|
||||||
|
|
|
@ -120,7 +120,7 @@ struct rpc_xprt {
|
||||||
struct kref kref; /* Reference count */
|
struct kref kref; /* Reference count */
|
||||||
struct rpc_xprt_ops * ops; /* transport methods */
|
struct rpc_xprt_ops * ops; /* transport methods */
|
||||||
|
|
||||||
struct rpc_timeout timeout; /* timeout parms */
|
const struct rpc_timeout *timeout; /* timeout parms */
|
||||||
struct sockaddr_storage addr; /* server address */
|
struct sockaddr_storage addr; /* server address */
|
||||||
size_t addrlen; /* size of server address */
|
size_t addrlen; /* size of server address */
|
||||||
int prot; /* IP protocol */
|
int prot; /* IP protocol */
|
||||||
|
@ -191,7 +191,6 @@ struct xprt_create {
|
||||||
struct sockaddr * srcaddr; /* optional local address */
|
struct sockaddr * srcaddr; /* optional local address */
|
||||||
struct sockaddr * dstaddr; /* remote peer address */
|
struct sockaddr * dstaddr; /* remote peer address */
|
||||||
size_t addrlen;
|
size_t addrlen;
|
||||||
struct rpc_timeout * timeout; /* optional timeout parameters */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xprt_class {
|
struct xprt_class {
|
||||||
|
|
|
@ -188,8 +188,15 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
|
||||||
if (!xprt_bound(clnt->cl_xprt))
|
if (!xprt_bound(clnt->cl_xprt))
|
||||||
clnt->cl_autobind = 1;
|
clnt->cl_autobind = 1;
|
||||||
|
|
||||||
|
clnt->cl_timeout = xprt->timeout;
|
||||||
|
if (args->timeout != NULL) {
|
||||||
|
memcpy(&clnt->cl_timeout_default, args->timeout,
|
||||||
|
sizeof(clnt->cl_timeout_default));
|
||||||
|
clnt->cl_timeout = &clnt->cl_timeout_default;
|
||||||
|
}
|
||||||
|
|
||||||
clnt->cl_rtt = &clnt->cl_rtt_default;
|
clnt->cl_rtt = &clnt->cl_rtt_default;
|
||||||
rpc_init_rtt(&clnt->cl_rtt_default, xprt->timeout.to_initval);
|
rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
|
||||||
|
|
||||||
kref_init(&clnt->cl_kref);
|
kref_init(&clnt->cl_kref);
|
||||||
|
|
||||||
|
@ -251,7 +258,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
|
||||||
.srcaddr = args->saddress,
|
.srcaddr = args->saddress,
|
||||||
.dstaddr = args->address,
|
.dstaddr = args->address,
|
||||||
.addrlen = args->addrsize,
|
.addrlen = args->addrsize,
|
||||||
.timeout = args->timeout
|
|
||||||
};
|
};
|
||||||
char servername[48];
|
char servername[48];
|
||||||
|
|
||||||
|
@ -348,7 +354,7 @@ rpc_clone_client(struct rpc_clnt *clnt)
|
||||||
new->cl_autobind = 0;
|
new->cl_autobind = 0;
|
||||||
INIT_LIST_HEAD(&new->cl_tasks);
|
INIT_LIST_HEAD(&new->cl_tasks);
|
||||||
spin_lock_init(&new->cl_lock);
|
spin_lock_init(&new->cl_lock);
|
||||||
rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
|
rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval);
|
||||||
new->cl_metrics = rpc_alloc_iostats(clnt);
|
new->cl_metrics = rpc_alloc_iostats(clnt);
|
||||||
if (new->cl_metrics == NULL)
|
if (new->cl_metrics == NULL)
|
||||||
goto out_no_stats;
|
goto out_no_stats;
|
||||||
|
|
|
@ -501,9 +501,10 @@ EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_def);
|
||||||
void xprt_set_retrans_timeout_rtt(struct rpc_task *task)
|
void xprt_set_retrans_timeout_rtt(struct rpc_task *task)
|
||||||
{
|
{
|
||||||
int timer = task->tk_msg.rpc_proc->p_timer;
|
int timer = task->tk_msg.rpc_proc->p_timer;
|
||||||
struct rpc_rtt *rtt = task->tk_client->cl_rtt;
|
struct rpc_clnt *clnt = task->tk_client;
|
||||||
|
struct rpc_rtt *rtt = clnt->cl_rtt;
|
||||||
struct rpc_rqst *req = task->tk_rqstp;
|
struct rpc_rqst *req = task->tk_rqstp;
|
||||||
unsigned long max_timeout = req->rq_xprt->timeout.to_maxval;
|
unsigned long max_timeout = clnt->cl_timeout->to_maxval;
|
||||||
|
|
||||||
task->tk_timeout = rpc_calc_rto(rtt, timer);
|
task->tk_timeout = rpc_calc_rto(rtt, timer);
|
||||||
task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries;
|
task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries;
|
||||||
|
@ -514,7 +515,7 @@ EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_rtt);
|
||||||
|
|
||||||
static void xprt_reset_majortimeo(struct rpc_rqst *req)
|
static void xprt_reset_majortimeo(struct rpc_rqst *req)
|
||||||
{
|
{
|
||||||
struct rpc_timeout *to = &req->rq_xprt->timeout;
|
const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout;
|
||||||
|
|
||||||
req->rq_majortimeo = req->rq_timeout;
|
req->rq_majortimeo = req->rq_timeout;
|
||||||
if (to->to_exponential)
|
if (to->to_exponential)
|
||||||
|
@ -534,7 +535,7 @@ static void xprt_reset_majortimeo(struct rpc_rqst *req)
|
||||||
int xprt_adjust_timeout(struct rpc_rqst *req)
|
int xprt_adjust_timeout(struct rpc_rqst *req)
|
||||||
{
|
{
|
||||||
struct rpc_xprt *xprt = req->rq_xprt;
|
struct rpc_xprt *xprt = req->rq_xprt;
|
||||||
struct rpc_timeout *to = &xprt->timeout;
|
const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
if (time_before(jiffies, req->rq_majortimeo)) {
|
if (time_before(jiffies, req->rq_majortimeo)) {
|
||||||
|
@ -928,7 +929,7 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
|
||||||
{
|
{
|
||||||
struct rpc_rqst *req = task->tk_rqstp;
|
struct rpc_rqst *req = task->tk_rqstp;
|
||||||
|
|
||||||
req->rq_timeout = xprt->timeout.to_initval;
|
req->rq_timeout = task->tk_client->cl_timeout->to_initval;
|
||||||
req->rq_task = task;
|
req->rq_task = task;
|
||||||
req->rq_xprt = xprt;
|
req->rq_xprt = xprt;
|
||||||
req->rq_buffer = NULL;
|
req->rq_buffer = NULL;
|
||||||
|
|
|
@ -332,7 +332,7 @@ xprt_setup_rdma(struct xprt_create *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 60 second timeout, no retries */
|
/* 60 second timeout, no retries */
|
||||||
memcpy(&xprt->timeout, &xprt_rdma_default_timeout, sizeof(xprt->timeout));
|
xprt->timeout = &xprt_rdma_default_timeout;
|
||||||
xprt->bind_timeout = (60U * HZ);
|
xprt->bind_timeout = (60U * HZ);
|
||||||
xprt->connect_timeout = (60U * HZ);
|
xprt->connect_timeout = (60U * HZ);
|
||||||
xprt->reestablish_timeout = (5U * HZ);
|
xprt->reestablish_timeout = (5U * HZ);
|
||||||
|
|
|
@ -1912,7 +1912,6 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
|
||||||
struct sockaddr *addr = args->dstaddr;
|
struct sockaddr *addr = args->dstaddr;
|
||||||
struct rpc_xprt *xprt;
|
struct rpc_xprt *xprt;
|
||||||
struct sock_xprt *transport;
|
struct sock_xprt *transport;
|
||||||
const struct rpc_timeout *timeo = &xs_udp_default_timeout;
|
|
||||||
|
|
||||||
xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries);
|
xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries);
|
||||||
if (IS_ERR(xprt))
|
if (IS_ERR(xprt))
|
||||||
|
@ -1931,9 +1930,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
|
||||||
|
|
||||||
xprt->ops = &xs_udp_ops;
|
xprt->ops = &xs_udp_ops;
|
||||||
|
|
||||||
if (args->timeout != NULL)
|
xprt->timeout = &xs_udp_default_timeout;
|
||||||
timeo = args->timeout;
|
|
||||||
memcpy(&xprt->timeout, timeo, sizeof(xprt->timeout));
|
|
||||||
|
|
||||||
switch (addr->sa_family) {
|
switch (addr->sa_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
@ -1984,7 +1981,6 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
|
||||||
struct sockaddr *addr = args->dstaddr;
|
struct sockaddr *addr = args->dstaddr;
|
||||||
struct rpc_xprt *xprt;
|
struct rpc_xprt *xprt;
|
||||||
struct sock_xprt *transport;
|
struct sock_xprt *transport;
|
||||||
const struct rpc_timeout *timeo = &xs_tcp_default_timeout;
|
|
||||||
|
|
||||||
xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
|
xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
|
||||||
if (IS_ERR(xprt))
|
if (IS_ERR(xprt))
|
||||||
|
@ -2001,10 +1997,7 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
|
||||||
xprt->idle_timeout = XS_IDLE_DISC_TO;
|
xprt->idle_timeout = XS_IDLE_DISC_TO;
|
||||||
|
|
||||||
xprt->ops = &xs_tcp_ops;
|
xprt->ops = &xs_tcp_ops;
|
||||||
|
xprt->timeout = &xs_tcp_default_timeout;
|
||||||
if (args->timeout != NULL)
|
|
||||||
timeo = args->timeout;
|
|
||||||
memcpy(&xprt->timeout, timeo, sizeof(xprt->timeout));
|
|
||||||
|
|
||||||
switch (addr->sa_family) {
|
switch (addr->sa_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
|
Loading…
Reference in a new issue