Skip to content

Commit

Permalink
SUNRPC: Limit the reconnect backoff timer to the max RPC message timeout
Browse files Browse the repository at this point in the history
...and ensure that we propagate it to new transports on the same
client.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
  • Loading branch information
Trond Myklebust committed Aug 5, 2016
1 parent 0291017 commit 3851f1c
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
3 changes: 2 additions & 1 deletion include/linux/sunrpc/xprt.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ struct rpc_xprt {
struct work_struct task_cleanup;
struct timer_list timer;
unsigned long last_used,
idle_timeout;
idle_timeout,
max_reconnect_timeout;

/*
* Send stuff
Expand Down
3 changes: 3 additions & 0 deletions net/sunrpc/clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2638,6 +2638,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
{
struct rpc_xprt_switch *xps;
struct rpc_xprt *xprt;
unsigned long reconnect_timeout;
unsigned char resvport;
int ret = 0;

Expand All @@ -2649,6 +2650,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
return -EAGAIN;
}
resvport = xprt->resvport;
reconnect_timeout = xprt->max_reconnect_timeout;
rcu_read_unlock();

xprt = xprt_create_transport(xprtargs);
Expand All @@ -2657,6 +2659,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
goto out_put_switch;
}
xprt->resvport = resvport;
xprt->max_reconnect_timeout = reconnect_timeout;

rpc_xprt_switch_set_roundrobin(xps);
if (setup) {
Expand Down
18 changes: 12 additions & 6 deletions net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ static struct ctl_table sunrpc_table[] = {
* increase over time if the server is down or not responding.
*/
#define XS_TCP_INIT_REEST_TO (3U * HZ)
#define XS_TCP_MAX_REEST_TO (5U * 60 * HZ)

/*
* TCP idle timeout; client drops the transport socket if it is idle
Expand Down Expand Up @@ -2396,6 +2395,15 @@ static unsigned long xs_reconnect_delay(const struct rpc_xprt *xprt)
return 0;
}

static void xs_reconnect_backoff(struct rpc_xprt *xprt)
{
xprt->reestablish_timeout <<= 1;
if (xprt->reestablish_timeout > xprt->max_reconnect_timeout)
xprt->reestablish_timeout = xprt->max_reconnect_timeout;
if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
}

/**
* xs_connect - connect a socket to a remote endpoint
* @xprt: pointer to transport structure
Expand Down Expand Up @@ -2426,12 +2434,8 @@ static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)
xs_reset_transport(transport);

delay = xs_reconnect_delay(xprt);
xs_reconnect_backoff(xprt);

xprt->reestablish_timeout <<= 1;
if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
} else
dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);

Expand Down Expand Up @@ -2989,6 +2993,8 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
xprt->ops = &xs_tcp_ops;
xprt->timeout = &xs_tcp_default_timeout;

xprt->max_reconnect_timeout = xprt->timeout->to_maxval;

INIT_WORK(&transport->recv_worker, xs_tcp_data_receive_workfn);
INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_setup_socket);

Expand Down

0 comments on commit 3851f1c

Please sign in to comment.