diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/xprt.c | 29 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 2 |
2 files changed, 19 insertions, 12 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index e8d11bd6158e..0458319a1bdd 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -62,7 +62,23 @@ static inline void do_xprt_reserve(struct rpc_task *); | |||
62 | static void xprt_connect_status(struct rpc_task *task); | 62 | static void xprt_connect_status(struct rpc_task *task); |
63 | static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); | 63 | static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); |
64 | 64 | ||
65 | static int xprt_clear_backlog(struct rpc_xprt *xprt); | 65 | /* |
66 | * The transport code maintains an estimate on the maximum number of out- | ||
67 | * standing RPC requests, using a smoothed version of the congestion | ||
68 | * avoidance implemented in 44BSD. This is basically the Van Jacobson | ||
69 | * congestion algorithm: If a retransmit occurs, the congestion window is | ||
70 | * halved; otherwise, it is incremented by 1/cwnd when | ||
71 | * | ||
72 | * - a reply is received and | ||
73 | * - a full number of requests are outstanding and | ||
74 | * - the congestion window hasn't been updated recently. | ||
75 | */ | ||
76 | #define RPC_CWNDSHIFT (8U) | ||
77 | #define RPC_CWNDSCALE (1U << RPC_CWNDSHIFT) | ||
78 | #define RPC_INITCWND RPC_CWNDSCALE | ||
79 | #define RPC_MAXCWND(xprt) ((xprt)->max_reqs << RPC_CWNDSHIFT) | ||
80 | |||
81 | #define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd) | ||
66 | 82 | ||
67 | /** | 83 | /** |
68 | * xprt_reserve_xprt - serialize write access to transports | 84 | * xprt_reserve_xprt - serialize write access to transports |
@@ -850,7 +866,7 @@ void xprt_release(struct rpc_task *task) | |||
850 | 866 | ||
851 | spin_lock(&xprt->reserve_lock); | 867 | spin_lock(&xprt->reserve_lock); |
852 | list_add(&req->rq_list, &xprt->free); | 868 | list_add(&req->rq_list, &xprt->free); |
853 | xprt_clear_backlog(xprt); | 869 | rpc_wake_up_next(&xprt->backlog); |
854 | spin_unlock(&xprt->reserve_lock); | 870 | spin_unlock(&xprt->reserve_lock); |
855 | } | 871 | } |
856 | 872 | ||
@@ -902,7 +918,6 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc | |||
902 | 918 | ||
903 | spin_lock_init(&xprt->transport_lock); | 919 | spin_lock_init(&xprt->transport_lock); |
904 | spin_lock_init(&xprt->reserve_lock); | 920 | spin_lock_init(&xprt->reserve_lock); |
905 | init_waitqueue_head(&xprt->cong_wait); | ||
906 | 921 | ||
907 | INIT_LIST_HEAD(&xprt->free); | 922 | INIT_LIST_HEAD(&xprt->free); |
908 | INIT_LIST_HEAD(&xprt->recv); | 923 | INIT_LIST_HEAD(&xprt->recv); |
@@ -911,6 +926,7 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc | |||
911 | xprt->timer.function = xprt_init_autodisconnect; | 926 | xprt->timer.function = xprt_init_autodisconnect; |
912 | xprt->timer.data = (unsigned long) xprt; | 927 | xprt->timer.data = (unsigned long) xprt; |
913 | xprt->last_used = jiffies; | 928 | xprt->last_used = jiffies; |
929 | xprt->cwnd = RPC_INITCWND; | ||
914 | 930 | ||
915 | rpc_init_wait_queue(&xprt->pending, "xprt_pending"); | 931 | rpc_init_wait_queue(&xprt->pending, "xprt_pending"); |
916 | rpc_init_wait_queue(&xprt->sending, "xprt_sending"); | 932 | rpc_init_wait_queue(&xprt->sending, "xprt_sending"); |
@@ -955,16 +971,9 @@ static void xprt_shutdown(struct rpc_xprt *xprt) | |||
955 | rpc_wake_up(&xprt->resend); | 971 | rpc_wake_up(&xprt->resend); |
956 | xprt_wake_pending_tasks(xprt, -EIO); | 972 | xprt_wake_pending_tasks(xprt, -EIO); |
957 | rpc_wake_up(&xprt->backlog); | 973 | rpc_wake_up(&xprt->backlog); |
958 | wake_up(&xprt->cong_wait); | ||
959 | del_timer_sync(&xprt->timer); | 974 | del_timer_sync(&xprt->timer); |
960 | } | 975 | } |
961 | 976 | ||
962 | static int xprt_clear_backlog(struct rpc_xprt *xprt) { | ||
963 | rpc_wake_up_next(&xprt->backlog); | ||
964 | wake_up(&xprt->cong_wait); | ||
965 | return 1; | ||
966 | } | ||
967 | |||
968 | /** | 977 | /** |
969 | * xprt_destroy - destroy an RPC transport, killing off all requests. | 978 | * xprt_destroy - destroy an RPC transport, killing off all requests. |
970 | * @xprt: transport to destroy | 979 | * @xprt: transport to destroy |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 7e5e020fe78d..26402c063f00 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1100,7 +1100,6 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1100 | xprt->prot = IPPROTO_UDP; | 1100 | xprt->prot = IPPROTO_UDP; |
1101 | xprt->port = XS_MAX_RESVPORT; | 1101 | xprt->port = XS_MAX_RESVPORT; |
1102 | xprt->tsh_size = 0; | 1102 | xprt->tsh_size = 0; |
1103 | xprt->cwnd = RPC_INITCWND; | ||
1104 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | 1103 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; |
1105 | /* XXX: header size can vary due to auth type, IPv6, etc. */ | 1104 | /* XXX: header size can vary due to auth type, IPv6, etc. */ |
1106 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); | 1105 | xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); |
@@ -1139,7 +1138,6 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1139 | xprt->prot = IPPROTO_TCP; | 1138 | xprt->prot = IPPROTO_TCP; |
1140 | xprt->port = XS_MAX_RESVPORT; | 1139 | xprt->port = XS_MAX_RESVPORT; |
1141 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | 1140 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); |
1142 | xprt->cwnd = RPC_MAXCWND(xprt); | ||
1143 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; | 1141 | xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; |
1144 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | 1142 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; |
1145 | 1143 | ||