瀏覽代碼

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>
Trond Myklebust 17 年之前
父節點
當前提交
ba7392bb37
共有 6 個文件被更改,包括 22 次插入21 次删除
  1. 3 1
      include/linux/sunrpc/clnt.h
  2. 1 2
      include/linux/sunrpc/xprt.h
  3. 9 3
      net/sunrpc/clnt.c
  4. 6 5
      net/sunrpc/xprt.c
  5. 1 1
      net/sunrpc/xprtrdma/transport.c
  6. 2 9
      net/sunrpc/xprtsock.c

+ 3 - 1
include/linux/sunrpc/clnt.h

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

+ 1 - 2
include/linux/sunrpc/xprt.h

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

+ 9 - 3
net/sunrpc/clnt.c

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

+ 6 - 5
net/sunrpc/xprt.c

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

+ 1 - 1
net/sunrpc/xprtrdma/transport.c

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

+ 2 - 9
net/sunrpc/xprtsock.c

@@ -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)
-		timeo = args->timeout;
-	memcpy(&xprt->timeout, timeo, sizeof(xprt->timeout));
+	xprt->timeout = &xs_udp_default_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;
-
-	if (args->timeout != NULL)
-		timeo = args->timeout;
-	memcpy(&xprt->timeout, timeo, sizeof(xprt->timeout));
+	xprt->timeout = &xs_tcp_default_timeout;
 
 
 	switch (addr->sa_family) {
 	switch (addr->sa_family) {
 	case AF_INET:
 	case AF_INET: