]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: NeilBrown <neilb@suse.de> |
2 | Subject: reset TCP connect timeout on successful connection. | |
3 | Patch-mainline: no - see below | |
4 | References: bnc#498708 | |
5 | ||
6 | Currently, every time an NFS server closes a TCP connection, the | |
7 | client will double its time out (up to 300 seconds) before attempting | |
8 | to reconnect. | |
9 | The timeout should only double while it fails. On success it should | |
10 | reset the timeout. | |
11 | ||
12 | This patch resets the timeout on a successful connection. | |
13 | It also ensures that we the timeout it doubled, it does not remain at | |
14 | 0. This should fix a behaviour which has been observed where the | |
15 | client hammers on the server until it accepts a connection. | |
16 | ||
17 | Note: this has not been accepted upstream. | |
18 | The stated reason is that some (Netapp?) servers are prone to accept | |
19 | a connection and then drop it immediately. This would defeat the backoff. | |
20 | While this should be fixed there are complexities in getting it right, | |
21 | and the current patch is at least an improvement. | |
22 | (there where already cases where the client would retry at a high | |
23 | rate and the new case is, I think, quite remote). | |
24 | When things are sorted out with upstream, we can get a better fix. | |
25 | ||
26 | Signed-off-by: NeilBrown <neilb@suse.de> | |
27 | ||
28 | --- | |
29 | net/sunrpc/xprtsock.c | 3 +++ | |
30 | 1 file changed, 3 insertions(+) | |
31 | ||
32 | --- a/net/sunrpc/xprtsock.c | |
33 | +++ b/net/sunrpc/xprtsock.c | |
34 | @@ -1143,6 +1143,7 @@ static void xs_tcp_state_change(struct s | |
35 | TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; | |
36 | ||
37 | xprt_wake_pending_tasks(xprt, 0); | |
38 | + xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | |
39 | } | |
40 | spin_unlock_bh(&xprt->transport_lock); | |
41 | break; | |
42 | @@ -1785,6 +1786,8 @@ static void xs_connect(struct rpc_task * | |
43 | &transport->connect_worker, | |
44 | xprt->reestablish_timeout); | |
45 | xprt->reestablish_timeout <<= 1; | |
46 | + if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) | |
47 | + xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | |
48 | if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) | |
49 | xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; | |
50 | } else { |