diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 88ac71fcd335..06c2d95484e0 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -41,6 +41,50 @@ | |||
41 | */ | 41 | */ |
42 | #define XS_SENDMSG_RETRY (10U) | 42 | #define XS_SENDMSG_RETRY (10U) |
43 | 43 | ||
44 | /* | ||
45 | * Time out for an RPC UDP socket connect. UDP socket connects are | ||
46 | * synchronous, but we set a timeout anyway in case of resource | ||
47 | * exhaustion on the local host. | ||
48 | */ | ||
49 | #define XS_UDP_CONN_TO (5U * HZ) | ||
50 | |||
51 | /* | ||
52 | * Wait duration for an RPC TCP connection to be established. Solaris | ||
53 | * NFS over TCP uses 60 seconds, for example, which is in line with how | ||
54 | * long a server takes to reboot. | ||
55 | */ | ||
56 | #define XS_TCP_CONN_TO (60U * HZ) | ||
57 | |||
58 | /* | ||
59 | * Wait duration for a reply from the RPC portmapper. | ||
60 | */ | ||
61 | #define XS_BIND_TO (60U * HZ) | ||
62 | |||
63 | /* | ||
64 | * Delay if a UDP socket connect error occurs. This is most likely some | ||
65 | * kind of resource problem on the local host. | ||
66 | */ | ||
67 | #define XS_UDP_REEST_TO (2U * HZ) | ||
68 | |||
69 | /* | ||
70 | * The reestablish timeout allows clients to delay for a bit before attempting | ||
71 | * to reconnect to a server that just dropped our connection. | ||
72 | * | ||
73 | * We implement an exponential backoff when trying to reestablish a TCP | ||
74 | * transport connection with the server. Some servers like to drop a TCP | ||
75 | * connection when they are overworked, so we start with a short timeout and | ||
76 | * increase over time if the server is down or not responding. | ||
77 | */ | ||
78 | #define XS_TCP_INIT_REEST_TO (3U * HZ) | ||
79 | #define XS_TCP_MAX_REEST_TO (5U * 60 * HZ) | ||
80 | |||
81 | /* | ||
82 | * TCP idle timeout; client drops the transport socket if it is idle | ||
83 | * for this long. Note that we also timeout UDP sockets to prevent | ||
84 | * holding port numbers when there is no RPC traffic. | ||
85 | */ | ||
86 | #define XS_IDLE_DISC_TO (5U * 60 * HZ) | ||
87 | |||
44 | #ifdef RPC_DEBUG | 88 | #ifdef RPC_DEBUG |
45 | # undef RPC_DEBUG_DATA | 89 | # undef RPC_DEBUG_DATA |
46 | # define RPCDBG_FACILITY RPCDBG_TRANS | 90 | # define RPCDBG_FACILITY RPCDBG_TRANS |
@@ -739,6 +783,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
739 | xprt->tcp_reclen = 0; | 783 | xprt->tcp_reclen = 0; |
740 | xprt->tcp_copied = 0; | 784 | xprt->tcp_copied = 0; |
741 | xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID; | 785 | xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID; |
786 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
742 | xprt_wake_pending_tasks(xprt, 0); | 787 | xprt_wake_pending_tasks(xprt, 0); |
743 | } | 788 | } |
744 | spin_unlock_bh(&xprt->transport_lock); | 789 | spin_unlock_bh(&xprt->transport_lock); |
@@ -1066,6 +1111,13 @@ out_clear: | |||
1066 | * @task: address of RPC task that manages state of connect request | 1111 | * @task: address of RPC task that manages state of connect request |
1067 | * | 1112 | * |
1068 | * TCP: If the remote end dropped the connection, delay reconnecting. | 1113 | * TCP: If the remote end dropped the connection, delay reconnecting. |
1114 | * | ||
1115 | * UDP socket connects are synchronous, but we use a work queue anyway | ||
1116 | * to guarantee that even unprivileged user processes can set up a | ||
1117 | * socket on a privileged port. | ||
1118 | * | ||
1119 | * If a UDP socket connect fails, the delay behavior here prevents | ||
1120 | * retry floods (hard mounts). | ||
1069 | */ | 1121 | */ |
1070 | static void xs_connect(struct rpc_task *task) | 1122 | static void xs_connect(struct rpc_task *task) |
1071 | { | 1123 | { |
@@ -1075,9 +1127,13 @@ static void xs_connect(struct rpc_task *task) | |||
1075 | return; | 1127 | return; |
1076 | 1128 | ||
1077 | if (xprt->sock != NULL) { | 1129 | if (xprt->sock != NULL) { |
1078 | dprintk("RPC: xs_connect delayed xprt %p\n", xprt); | 1130 | dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n", |
1131 | xprt, xprt->reestablish_timeout / HZ); | ||
1079 | schedule_delayed_work(&xprt->connect_worker, | 1132 | schedule_delayed_work(&xprt->connect_worker, |
1080 | RPC_REESTABLISH_TIMEOUT); | 1133 | xprt->reestablish_timeout); |
1134 | xprt->reestablish_timeout <<= 1; | ||
1135 | if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) | ||
1136 | xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; | ||
1081 | } else { | 1137 | } else { |
1082 | dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); | 1138 | dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); |
1083 | schedule_work(&xprt->connect_worker); | 1139 | schedule_work(&xprt->connect_worker); |
@@ -1139,6 +1195,10 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1139 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); | 1195 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); |
1140 | 1196 | ||
1141 | INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt); | 1197 | INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt); |
1198 | xprt->bind_timeout = XS_BIND_TO; | ||
1199 | xprt->connect_timeout = XS_UDP_CONN_TO; | ||
1200 | xprt->reestablish_timeout = XS_UDP_REEST_TO; | ||
1201 | xprt->idle_timeout = XS_IDLE_DISC_TO; | ||
1142 | 1202 | ||
1143 | xprt->ops = &xs_udp_ops; | 1203 | xprt->ops = &xs_udp_ops; |
1144 | 1204 | ||
@@ -1176,6 +1236,10 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1176 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 1236 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
1177 | 1237 | ||
1178 | INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); | 1238 | INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); |
1239 | xprt->bind_timeout = XS_BIND_TO; | ||
1240 | xprt->connect_timeout = XS_TCP_CONN_TO; | ||
1241 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
1242 | xprt->idle_timeout = XS_IDLE_DISC_TO; | ||
1179 | 1243 | ||
1180 | xprt->ops = &xs_tcp_ops; | 1244 | xprt->ops = &xs_tcp_ops; |
1181 | 1245 | ||