diff options
Diffstat (limited to 'net/sunrpc/svcsock.c')
| -rw-r--r-- | net/sunrpc/svcsock.c | 35 | 
1 files changed, 28 insertions, 7 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index af3198814c15..9d504234af4a 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -345,6 +345,7 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,  	lock_sock(sock->sk);  	sock->sk->sk_sndbuf = snd * 2;  	sock->sk->sk_rcvbuf = rcv * 2; +	sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK;  	release_sock(sock->sk);  #endif  } @@ -796,6 +797,23 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)  		test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags),  		test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags)); +	if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags)) +		/* sndbuf needs to have room for one request +		 * per thread, otherwise we can stall even when the +		 * network isn't a bottleneck. +		 * +		 * We count all threads rather than threads in a +		 * particular pool, which provides an upper bound +		 * on the number of threads which will access the socket. +		 * +		 * rcvbuf just needs to be able to hold a few requests. +		 * Normally they will be removed from the queue +		 * as soon a a complete request arrives. +		 */ +		svc_sock_setbufsize(svsk->sk_sock, +				    (serv->sv_nrthreads+3) * serv->sv_max_mesg, +				    3 * serv->sv_max_mesg); +  	clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);  	/* Receive data. If we haven't got the record length yet, get @@ -1043,6 +1061,15 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)  		tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; +		/* initialise setting must have enough space to +		 * receive and respond to one request. +		 * svc_tcp_recvfrom will re-adjust if necessary +		 */ +		svc_sock_setbufsize(svsk->sk_sock, +				    3 * svsk->sk_xprt.xpt_server->sv_max_mesg, +				    3 * svsk->sk_xprt.xpt_server->sv_max_mesg); + +		set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);  		set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);  		if (sk->sk_state != TCP_ESTABLISHED)  			set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); @@ -1112,14 +1139,8 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,  	/* Initialize the socket */  	if (sock->type == SOCK_DGRAM)  		svc_udp_init(svsk, serv); -	else { -		/* initialise setting must have enough space to -		 * receive and respond to one request. -		 */ -		svc_sock_setbufsize(svsk->sk_sock, 4 * serv->sv_max_mesg, -					4 * serv->sv_max_mesg); +	else  		svc_tcp_init(svsk, serv); -	}  	dprintk("svc: svc_setup_socket created %p (inet %p)\n",  				svsk, svsk->sk_sk);  | 
