diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/clnt.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 5 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 68 |
3 files changed, 69 insertions, 6 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index cc1b773a79d3..24b44e73f391 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -740,7 +740,7 @@ call_bind(struct rpc_task *task) | |||
740 | task->tk_action = call_connect; | 740 | task->tk_action = call_connect; |
741 | if (!clnt->cl_port) { | 741 | if (!clnt->cl_port) { |
742 | task->tk_action = call_bind_status; | 742 | task->tk_action = call_bind_status; |
743 | task->tk_timeout = RPC_CONNECT_TIMEOUT; | 743 | task->tk_timeout = task->tk_xprt->bind_timeout; |
744 | rpc_getport(task, clnt); | 744 | rpc_getport(task, clnt); |
745 | } | 745 | } |
746 | } | 746 | } |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 0458319a1bdd..215be0d0ef6b 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -551,7 +551,7 @@ void xprt_connect(struct rpc_task *task) | |||
551 | if (task->tk_rqstp) | 551 | if (task->tk_rqstp) |
552 | task->tk_rqstp->rq_bytes_sent = 0; | 552 | task->tk_rqstp->rq_bytes_sent = 0; |
553 | 553 | ||
554 | task->tk_timeout = RPC_CONNECT_TIMEOUT; | 554 | task->tk_timeout = xprt->connect_timeout; |
555 | rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); | 555 | rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); |
556 | xprt->ops->connect(task); | 556 | xprt->ops->connect(task); |
557 | } | 557 | } |
@@ -763,7 +763,6 @@ void xprt_transmit(struct rpc_task *task) | |||
763 | 763 | ||
764 | switch (status) { | 764 | switch (status) { |
765 | case -ECONNREFUSED: | 765 | case -ECONNREFUSED: |
766 | task->tk_timeout = RPC_REESTABLISH_TIMEOUT; | ||
767 | rpc_sleep_on(&xprt->sending, task, NULL, NULL); | 766 | rpc_sleep_on(&xprt->sending, task, NULL, NULL); |
768 | case -EAGAIN: | 767 | case -EAGAIN: |
769 | case -ENOTCONN: | 768 | case -ENOTCONN: |
@@ -857,7 +856,7 @@ void xprt_release(struct rpc_task *task) | |||
857 | xprt->last_used = jiffies; | 856 | xprt->last_used = jiffies; |
858 | if (list_empty(&xprt->recv) && !xprt->shutdown) | 857 | if (list_empty(&xprt->recv) && !xprt->shutdown) |
859 | mod_timer(&xprt->timer, | 858 | mod_timer(&xprt->timer, |
860 | xprt->last_used + RPC_IDLE_DISCONNECT_TIMEOUT); | 859 | xprt->last_used + xprt->idle_timeout); |
861 | spin_unlock_bh(&xprt->transport_lock); | 860 | spin_unlock_bh(&xprt->transport_lock); |
862 | task->tk_rqstp = NULL; | 861 | task->tk_rqstp = NULL; |
863 | memset(req, 0, sizeof(*req)); /* mark unused */ | 862 | memset(req, 0, sizeof(*req)); /* mark unused */ |
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 | ||