aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-05-18 17:47:56 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-06-18 22:58:51 -0400
commit47fcb03fefee2501e79176932a4184fc24d6f8ec (patch)
treecb8eb34c5e54ce278b54cb6f9c820f564c183574 /net/sunrpc
parentab52ae6db035fa425f90146327ab7d2c5d3e5654 (diff)
SUNRPC: Fix the TCP server's send buffer accounting
Currently, the sunrpc server is refusing to allow us to process new RPC calls if the TCP send buffer is 2/3 full, even if we do actually have enough free space to guarantee that we can send another request. The following patch fixes svc_tcp_has_wspace() so that we only stop processing requests if we know that the socket buffer cannot possibly fit another reply. It also fixes the tcp write_space() callback so that we only clear the SOCK_NOSPACE flag when the TCP send buffer is less than 2/3 full. This should ensure that the send window will grow as per the standard TCP socket code. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/svcsock.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 004a2f9dc432..b09c80c56ee3 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -380,6 +380,7 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,
380 sock->sk->sk_sndbuf = snd * 2; 380 sock->sk->sk_sndbuf = snd * 2;
381 sock->sk->sk_rcvbuf = rcv * 2; 381 sock->sk->sk_rcvbuf = rcv * 2;
382 sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK; 382 sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK;
383 sock->sk->sk_write_space(sock->sk);
383 release_sock(sock->sk); 384 release_sock(sock->sk);
384#endif 385#endif
385} 386}
@@ -421,6 +422,15 @@ static void svc_write_space(struct sock *sk)
421 } 422 }
422} 423}
423 424
425static void svc_tcp_write_space(struct sock *sk)
426{
427 struct socket *sock = sk->sk_socket;
428
429 if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && sock)
430 clear_bit(SOCK_NOSPACE, &sock->flags);
431 svc_write_space(sk);
432}
433
424/* 434/*
425 * Copy the UDP datagram's destination address to the rqstp structure. 435 * Copy the UDP datagram's destination address to the rqstp structure.
426 * The 'destination' address in this case is the address to which the 436 * The 'destination' address in this case is the address to which the
@@ -1015,25 +1025,16 @@ static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
1015static int svc_tcp_has_wspace(struct svc_xprt *xprt) 1025static int svc_tcp_has_wspace(struct svc_xprt *xprt)
1016{ 1026{
1017 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); 1027 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
1018 struct svc_serv *serv = svsk->sk_xprt.xpt_server; 1028 struct svc_serv *serv = svsk->sk_xprt.xpt_server;
1019 int required; 1029 int required;
1020 int wspace;
1021 1030
1022 /* 1031 if (test_bit(XPT_LISTENER, &xprt->xpt_flags))
1023 * Set the SOCK_NOSPACE flag before checking the available 1032 return 1;
1024 * sock space. 1033 required = atomic_read(&xprt->xpt_reserved) + serv->sv_max_mesg;
1025 */ 1034 if (sk_stream_wspace(svsk->sk_sk) >= required)
1035 return 1;
1026 set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); 1036 set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
1027 required = atomic_read(&svsk->sk_xprt.xpt_reserved) + serv->sv_max_mesg; 1037 return 0;
1028 wspace = sk_stream_wspace(svsk->sk_sk);
1029
1030 if (wspace < sk_stream_min_wspace(svsk->sk_sk))
1031 return 0;
1032 if (required * 2 > wspace)
1033 return 0;
1034
1035 clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
1036 return 1;
1037} 1038}
1038 1039
1039static struct svc_xprt *svc_tcp_create(struct svc_serv *serv, 1040static struct svc_xprt *svc_tcp_create(struct svc_serv *serv,
@@ -1089,7 +1090,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
1089 dprintk("setting up TCP socket for reading\n"); 1090 dprintk("setting up TCP socket for reading\n");
1090 sk->sk_state_change = svc_tcp_state_change; 1091 sk->sk_state_change = svc_tcp_state_change;
1091 sk->sk_data_ready = svc_tcp_data_ready; 1092 sk->sk_data_ready = svc_tcp_data_ready;
1092 sk->sk_write_space = svc_write_space; 1093 sk->sk_write_space = svc_tcp_write_space;
1093 1094
1094 svsk->sk_reclen = 0; 1095 svsk->sk_reclen = 0;
1095 svsk->sk_tcplen = 0; 1096 svsk->sk_tcplen = 0;