Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03bf4b70 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

[PATCH] RPC: parametrize various transport connect timeouts



 Each transport implementation can now set unique bind, connect,
 reestablishment, and idle timeout values.  These are variables,
 allowing the values to be modified dynamically.  This permits
 exponential backoff of any of these values, for instance.

 As an example, we implement exponential backoff for the connection
 reestablishment timeout.

 Test-plan:
 Destructive testing (unplugging the network temporarily).  Connectathon
 with UDP and TCP.

 Signed-off-by: default avatarChuck Lever <cel@netapp.com>
 Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 3167e12c
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -369,8 +369,8 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned
	case IPPROTO_TCP:
		if (!to->to_initval)
			to->to_initval = 60 * HZ;
		if (to->to_initval > RPC_MAX_TCP_TIMEOUT)
			to->to_initval = RPC_MAX_TCP_TIMEOUT;
		if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
			to->to_initval = NFS_MAX_TCP_TIMEOUT;
		to->to_increment = to->to_initval;
		to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
		to->to_exponential = 0;
@@ -379,9 +379,9 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned
	default:
		if (!to->to_initval)
			to->to_initval = 11 * HZ / 10;
		if (to->to_initval > RPC_MAX_UDP_TIMEOUT)
			to->to_initval = RPC_MAX_UDP_TIMEOUT;
		to->to_maxval = RPC_MAX_UDP_TIMEOUT;
		if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
			to->to_initval = NFS_MAX_UDP_TIMEOUT;
		to->to_maxval = NFS_MAX_UDP_TIMEOUT;
		to->to_exponential = 1;
		break;
	}
+4 −0
Original line number Diff line number Diff line
@@ -41,6 +41,10 @@
#define NFS_MAX_FILE_IO_BUFFER_SIZE	32768
#define NFS_DEF_FILE_IO_BUFFER_SIZE	4096

/* Default timeout values */
#define NFS_MAX_UDP_TIMEOUT	(60*HZ)
#define NFS_MAX_TCP_TIMEOUT	(600*HZ)

/*
 * superblock magic number for NFS
 */
+6 −23
Original line number Diff line number Diff line
@@ -22,28 +22,6 @@ extern unsigned int xprt_tcp_slot_table_entries;
#define RPC_DEF_SLOT_TABLE	(16U)
#define RPC_MAX_SLOT_TABLE	(128U)

/* Default timeout values */
#define RPC_MAX_UDP_TIMEOUT	(60*HZ)
#define RPC_MAX_TCP_TIMEOUT	(600*HZ)

/*
 * Wait duration for an RPC TCP connection to be established.  Solaris
 * NFS over TCP uses 60 seconds, for example, which is in line with how
 * long a server takes to reboot.
 */
#define RPC_CONNECT_TIMEOUT	(60*HZ)

/*
 * Delay an arbitrary number of seconds before attempting to reconnect
 * after an error.
 */
#define RPC_REESTABLISH_TIMEOUT	(15*HZ)

/*
 * RPC transport idle timeout.
 */
#define RPC_IDLE_DISCONNECT_TIMEOUT	(5*60*HZ)

/*
 * RPC call and reply header size as number of 32bit words (verifier
 * size computed separately)
@@ -182,14 +160,19 @@ struct rpc_xprt {
	/*
	 * Connection of transports
	 */
	unsigned long		connect_timeout,
				bind_timeout,
				reestablish_timeout;
	struct work_struct	connect_worker;
	unsigned short		port;

	/*
	 * Disconnection of idle transports
	 */
	struct work_struct	task_cleanup;
	struct timer_list	timer;
	unsigned long		last_used;
	unsigned long		last_used,
				idle_timeout;

	/*
	 * Send stuff
+1 −1
Original line number Diff line number Diff line
@@ -740,7 +740,7 @@ call_bind(struct rpc_task *task)
	task->tk_action = call_connect;
	if (!clnt->cl_port) {
		task->tk_action = call_bind_status;
		task->tk_timeout = RPC_CONNECT_TIMEOUT;
		task->tk_timeout = task->tk_xprt->bind_timeout;
		rpc_getport(task, clnt);
	}
}
+2 −3
Original line number Diff line number Diff line
@@ -551,7 +551,7 @@ void xprt_connect(struct rpc_task *task)
		if (task->tk_rqstp)
			task->tk_rqstp->rq_bytes_sent = 0;

		task->tk_timeout = RPC_CONNECT_TIMEOUT;
		task->tk_timeout = xprt->connect_timeout;
		rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL);
		xprt->ops->connect(task);
	}
@@ -763,7 +763,6 @@ void xprt_transmit(struct rpc_task *task)

	switch (status) {
	case -ECONNREFUSED:
		task->tk_timeout = RPC_REESTABLISH_TIMEOUT;
		rpc_sleep_on(&xprt->sending, task, NULL, NULL);
	case -EAGAIN:
	case -ENOTCONN:
@@ -857,7 +856,7 @@ void xprt_release(struct rpc_task *task)
	xprt->last_used = jiffies;
	if (list_empty(&xprt->recv) && !xprt->shutdown)
		mod_timer(&xprt->timer,
				xprt->last_used + RPC_IDLE_DISCONNECT_TIMEOUT);
				xprt->last_used + xprt->idle_timeout);
	spin_unlock_bh(&xprt->transport_lock);
	task->tk_rqstp = NULL;
	memset(req, 0, sizeof(*req));	/* mark unused */
Loading