SUNRPC: Add support for per-client timeout values
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 20 Dec 2007 21:03:55 +0000 (16:03 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 30 Jan 2008 07:05:59 +0000 (02:05 -0500)
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>
include/linux/sunrpc/clnt.h
include/linux/sunrpc/xprt.h
net/sunrpc/clnt.c
net/sunrpc/xprt.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtsock.c

index 4fc268a..51a3381 100644 (file)
@@ -46,6 +46,7 @@ struct rpc_clnt {
                                cl_autobind : 1;/* use getport() */
 
        struct rpc_rtt *        cl_rtt;         /* RTO estimator data */
+       const struct rpc_timeout *cl_timeout;   /* Timeout strategy */
 
        int                     cl_nodelen;     /* nodename length */
        char                    cl_nodename[UNX_MAXNODENAME];
@@ -54,6 +55,7 @@ struct rpc_clnt {
        struct dentry *         cl_dentry;      /* inode */
        struct rpc_clnt *       cl_parent;      /* Points to parent of clones */
        struct rpc_rtt          cl_rtt_default;
+       struct rpc_timeout      cl_timeout_default;
        struct rpc_program *    cl_program;
        char                    cl_inline_name[32];
 };
@@ -99,7 +101,7 @@ struct rpc_create_args {
        struct sockaddr         *address;
        size_t                  addrsize;
        struct sockaddr         *saddress;
-       struct rpc_timeout      *timeout;
+       const struct rpc_timeout *timeout;
        char                    *servername;
        struct rpc_program      *program;
        u32                     version;
index a00d4a4..c3364d8 100644 (file)
@@ -120,7 +120,7 @@ struct rpc_xprt {
        struct kref             kref;           /* Reference count */
        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 */
        size_t                  addrlen;        /* size of server address */
        int                     prot;           /* IP protocol */
@@ -191,7 +191,6 @@ struct xprt_create {
        struct sockaddr *       srcaddr;        /* optional local address */
        struct sockaddr *       dstaddr;        /* remote peer address */
        size_t                  addrlen;
-       struct rpc_timeout *    timeout;        /* optional timeout parameters */
 };
 
 struct xprt_class {
index 6a6b96e..a3c00da 100644 (file)
@@ -188,8 +188,15 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
        if (!xprt_bound(clnt->cl_xprt))
                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;
-       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);
 
@@ -251,7 +258,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
                .srcaddr = args->saddress,
                .dstaddr = args->address,
                .addrlen = args->addrsize,
-               .timeout = args->timeout
        };
        char servername[48];
 
@@ -348,7 +354,7 @@ rpc_clone_client(struct rpc_clnt *clnt)
        new->cl_autobind = 0;
        INIT_LIST_HEAD(&new->cl_tasks);
        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);
        if (new->cl_metrics == NULL)
                goto out_no_stats;
index 2bc9956..cfcade9 100644 (file)
@@ -501,9 +501,10 @@ EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_def);
 void xprt_set_retrans_timeout_rtt(struct rpc_task *task)
 {
        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;
-       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_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)
 {
-       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;
        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)
 {
        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;
 
        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;
 
-       req->rq_timeout = xprt->timeout.to_initval;
+       req->rq_timeout = task->tk_client->cl_timeout->to_initval;
        req->rq_task    = task;
        req->rq_xprt    = xprt;
        req->rq_buffer  = NULL;
index 39f1001..d1389af 100644 (file)
@@ -332,7 +332,7 @@ xprt_setup_rdma(struct xprt_create *args)
        }
 
        /* 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->connect_timeout = (60U * HZ);
        xprt->reestablish_timeout = (5U * HZ);
index d7b07ac..6ba329d 100644 (file)
@@ -1912,7 +1912,6 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
        struct sockaddr *addr = args->dstaddr;
        struct rpc_xprt *xprt;
        struct sock_xprt *transport;
-       const struct rpc_timeout *timeo = &xs_udp_default_timeout;
 
        xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries);
        if (IS_ERR(xprt))
@@ -1931,9 +1930,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
 
        xprt->ops = &xs_udp_ops;
 
-       if (args->timeout != NULL)
-               timeo = args->timeout;
-       memcpy(&xprt->timeout, timeo, sizeof(xprt->timeout));
+       xprt->timeout = &xs_udp_default_timeout;
 
        switch (addr->sa_family) {
        case AF_INET:
@@ -1984,7 +1981,6 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
        struct sockaddr *addr = args->dstaddr;
        struct rpc_xprt *xprt;
        struct sock_xprt *transport;
-       const struct rpc_timeout *timeo = &xs_tcp_default_timeout;
 
        xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
        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->ops = &xs_tcp_ops;
-
-       if (args->timeout != NULL)
-               timeo = args->timeout;
-       memcpy(&xprt->timeout, timeo, sizeof(xprt->timeout));
+       xprt->timeout = &xs_tcp_default_timeout;
 
        switch (addr->sa_family) {
        case AF_INET: