aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <cel@citi.umich.edu>2005-08-11 16:25:14 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-09-23 12:38:06 -0400
commiteab5c084b858fd95a873fc2b97de9a9ad937b4ed (patch)
tree6ba8287570ecc83fed1512bd4901df979221c2ab
parentda35187801732397a7e05fb9e77f3700cc35f5db (diff)
[PATCH] NFS: use a constant value for TCP retransmit timeouts
Implement a best practice: don't use exponential backoff when computing retransmit timeout values on TCP connections, but simply retransmit at regular intervals. This also fixes a bug introduced when xprt_reset_majortimeo() was added. Test-plan: Enable RPC debugging and watch timeout behavior on a NFS/TCP mount. Version: Thu, 11 Aug 2005 16:02:19 -0400 Signed-off-by: Chuck Lever <cel@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/inode.c73
-rw-r--r--net/sunrpc/xprt.c4
2 files changed, 37 insertions, 40 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 6922469d6fc5..b6a1ca508e60 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -358,6 +358,35 @@ out_no_root:
358 return no_root_error; 358 return no_root_error;
359} 359}
360 360
361static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans)
362{
363 to->to_initval = timeo * HZ / 10;
364 to->to_retries = retrans;
365 if (!to->to_retries)
366 to->to_retries = 2;
367
368 switch (proto) {
369 case IPPROTO_TCP:
370 if (!to->to_initval)
371 to->to_initval = 60 * HZ;
372 if (to->to_initval > RPC_MAX_TCP_TIMEOUT)
373 to->to_initval = RPC_MAX_TCP_TIMEOUT;
374 to->to_increment = to->to_initval;
375 to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
376 to->to_exponential = 0;
377 break;
378 case IPPROTO_UDP:
379 default:
380 if (!to->to_initval)
381 to->to_initval = 11 * HZ / 10;
382 if (to->to_initval > RPC_MAX_UDP_TIMEOUT)
383 to->to_initval = RPC_MAX_UDP_TIMEOUT;
384 to->to_maxval = RPC_MAX_UDP_TIMEOUT;
385 to->to_exponential = 1;
386 break;
387 }
388}
389
361/* 390/*
362 * Create an RPC client handle. 391 * Create an RPC client handle.
363 */ 392 */
@@ -367,22 +396,12 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
367 struct rpc_timeout timeparms; 396 struct rpc_timeout timeparms;
368 struct rpc_xprt *xprt = NULL; 397 struct rpc_xprt *xprt = NULL;
369 struct rpc_clnt *clnt = NULL; 398 struct rpc_clnt *clnt = NULL;
370 int tcp = (data->flags & NFS_MOUNT_TCP); 399 int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
371
372 /* Initialize timeout values */
373 timeparms.to_initval = data->timeo * HZ / 10;
374 timeparms.to_retries = data->retrans;
375 timeparms.to_maxval = tcp ? RPC_MAX_TCP_TIMEOUT : RPC_MAX_UDP_TIMEOUT;
376 timeparms.to_exponential = 1;
377 400
378 if (!timeparms.to_initval) 401 nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans);
379 timeparms.to_initval = (tcp ? 600 : 11) * HZ / 10;
380 if (!timeparms.to_retries)
381 timeparms.to_retries = 5;
382 402
383 /* create transport and client */ 403 /* create transport and client */
384 xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP, 404 xprt = xprt_create_proto(proto, &server->addr, &timeparms);
385 &server->addr, &timeparms);
386 if (IS_ERR(xprt)) { 405 if (IS_ERR(xprt)) {
387 dprintk("%s: cannot create RPC transport. Error = %ld\n", 406 dprintk("%s: cannot create RPC transport. Error = %ld\n",
388 __FUNCTION__, PTR_ERR(xprt)); 407 __FUNCTION__, PTR_ERR(xprt));
@@ -1674,7 +1693,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1674 struct rpc_clnt *clnt = NULL; 1693 struct rpc_clnt *clnt = NULL;
1675 struct rpc_timeout timeparms; 1694 struct rpc_timeout timeparms;
1676 rpc_authflavor_t authflavour; 1695 rpc_authflavor_t authflavour;
1677 int proto, err = -EIO; 1696 int err = -EIO;
1678 1697
1679 sb->s_blocksize_bits = 0; 1698 sb->s_blocksize_bits = 0;
1680 sb->s_blocksize = 0; 1699 sb->s_blocksize = 0;
@@ -1692,30 +1711,8 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1692 server->acdirmax = data->acdirmax*HZ; 1711 server->acdirmax = data->acdirmax*HZ;
1693 1712
1694 server->rpc_ops = &nfs_v4_clientops; 1713 server->rpc_ops = &nfs_v4_clientops;
1695 /* Initialize timeout values */
1696
1697 timeparms.to_initval = data->timeo * HZ / 10;
1698 timeparms.to_retries = data->retrans;
1699 timeparms.to_exponential = 1;
1700 if (!timeparms.to_retries)
1701 timeparms.to_retries = 5;
1702 1714
1703 proto = data->proto; 1715 nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans);
1704 /* Which IP protocol do we use? */
1705 switch (proto) {
1706 case IPPROTO_TCP:
1707 timeparms.to_maxval = RPC_MAX_TCP_TIMEOUT;
1708 if (!timeparms.to_initval)
1709 timeparms.to_initval = 600 * HZ / 10;
1710 break;
1711 case IPPROTO_UDP:
1712 timeparms.to_maxval = RPC_MAX_UDP_TIMEOUT;
1713 if (!timeparms.to_initval)
1714 timeparms.to_initval = 11 * HZ / 10;
1715 break;
1716 default:
1717 return -EINVAL;
1718 }
1719 1716
1720 clp = nfs4_get_client(&server->addr.sin_addr); 1717 clp = nfs4_get_client(&server->addr.sin_addr);
1721 if (!clp) { 1718 if (!clp) {
@@ -1740,7 +1737,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1740 1737
1741 down_write(&clp->cl_sem); 1738 down_write(&clp->cl_sem);
1742 if (IS_ERR(clp->cl_rpcclient)) { 1739 if (IS_ERR(clp->cl_rpcclient)) {
1743 xprt = xprt_create_proto(proto, &server->addr, &timeparms); 1740 xprt = xprt_create_proto(data->proto, &server->addr, &timeparms);
1744 if (IS_ERR(xprt)) { 1741 if (IS_ERR(xprt)) {
1745 up_write(&clp->cl_sem); 1742 up_write(&clp->cl_sem);
1746 err = PTR_ERR(xprt); 1743 err = PTR_ERR(xprt);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index b28ea0cc0cb7..0e4ffdaa0129 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -1453,7 +1453,7 @@ xprt_default_timeout(struct rpc_timeout *to, int proto)
1453 if (proto == IPPROTO_UDP) 1453 if (proto == IPPROTO_UDP)
1454 xprt_set_timeout(to, 5, 5 * HZ); 1454 xprt_set_timeout(to, 5, 5 * HZ);
1455 else 1455 else
1456 xprt_set_timeout(to, 5, 60 * HZ); 1456 xprt_set_timeout(to, 2, 60 * HZ);
1457} 1457}
1458 1458
1459/* 1459/*
@@ -1464,7 +1464,7 @@ xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr)
1464{ 1464{
1465 to->to_initval = 1465 to->to_initval =
1466 to->to_increment = incr; 1466 to->to_increment = incr;
1467 to->to_maxval = incr * retr; 1467 to->to_maxval = to->to_initval + (incr * retr);
1468 to->to_retries = retr; 1468 to->to_retries = retr;
1469 to->to_exponential = 0; 1469 to->to_exponential = 0;
1470} 1470}