aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-08-04 00:00:33 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-08-05 12:18:10 -0400
commit02910177aede34d6f49e2dc14b1c5c6cd468d94f (patch)
tree1f89ffbc5a8b1f1ea0eb82f86acd822237089518
parent206b3bb57481758b5fe98e90f47abb0f3fc0954e (diff)
SUNRPC: Fix reconnection timeouts
When the connect attempt fails and backs off, we should start the clock at the last connection attempt, not time at which we queue up the reconnect job. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--net/sunrpc/xprtsock.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index bf79212fdbf8..04b0c4190dd7 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2173,6 +2173,8 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
2173 write_unlock_bh(&sk->sk_callback_lock); 2173 write_unlock_bh(&sk->sk_callback_lock);
2174 } 2174 }
2175 xs_udp_do_set_buffer_size(xprt); 2175 xs_udp_do_set_buffer_size(xprt);
2176
2177 xprt->stat.connect_start = jiffies;
2176} 2178}
2177 2179
2178static void xs_udp_setup_socket(struct work_struct *work) 2180static void xs_udp_setup_socket(struct work_struct *work)
@@ -2384,6 +2386,16 @@ out:
2384 xprt_wake_pending_tasks(xprt, status); 2386 xprt_wake_pending_tasks(xprt, status);
2385} 2387}
2386 2388
2389static unsigned long xs_reconnect_delay(const struct rpc_xprt *xprt)
2390{
2391 unsigned long start, now = jiffies;
2392
2393 start = xprt->stat.connect_start + xprt->reestablish_timeout;
2394 if (time_after(start, now))
2395 return start - now;
2396 return 0;
2397}
2398
2387/** 2399/**
2388 * xs_connect - connect a socket to a remote endpoint 2400 * xs_connect - connect a socket to a remote endpoint
2389 * @xprt: pointer to transport structure 2401 * @xprt: pointer to transport structure
@@ -2401,6 +2413,7 @@ out:
2401static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task) 2413static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)
2402{ 2414{
2403 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 2415 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
2416 unsigned long delay = 0;
2404 2417
2405 WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport)); 2418 WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport));
2406 2419
@@ -2412,19 +2425,19 @@ static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)
2412 /* Start by resetting any existing state */ 2425 /* Start by resetting any existing state */
2413 xs_reset_transport(transport); 2426 xs_reset_transport(transport);
2414 2427
2415 queue_delayed_work(xprtiod_workqueue, 2428 delay = xs_reconnect_delay(xprt);
2416 &transport->connect_worker, 2429
2417 xprt->reestablish_timeout);
2418 xprt->reestablish_timeout <<= 1; 2430 xprt->reestablish_timeout <<= 1;
2419 if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) 2431 if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
2420 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 2432 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
2421 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) 2433 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
2422 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; 2434 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
2423 } else { 2435 } else
2424 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); 2436 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
2425 queue_delayed_work(xprtiod_workqueue, 2437
2426 &transport->connect_worker, 0); 2438 queue_delayed_work(xprtiod_workqueue,
2427 } 2439 &transport->connect_worker,
2440 delay);
2428} 2441}
2429 2442
2430/** 2443/**