diff options
Diffstat (limited to 'net/sunrpc')
| -rw-r--r-- | net/sunrpc/svc_xprt.c | 10 | ||||
| -rw-r--r-- | net/sunrpc/svcsock.c | 2 | ||||
| -rw-r--r-- | net/sunrpc/xprt.c | 34 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/transport.c | 1 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 3 | 
5 files changed, 29 insertions, 21 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 88f2bf67196..bac973a3136 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -316,7 +316,6 @@ static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt)   */  void svc_xprt_enqueue(struct svc_xprt *xprt)  { -	struct svc_serv	*serv = xprt->xpt_server;  	struct svc_pool *pool;  	struct svc_rqst	*rqstp;  	int cpu; @@ -362,8 +361,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)  				rqstp, rqstp->rq_xprt);  		rqstp->rq_xprt = xprt;  		svc_xprt_get(xprt); -		rqstp->rq_reserved = serv->sv_max_mesg; -		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);  		pool->sp_stats.threads_woken++;  		wake_up(&rqstp->rq_wait);  	} else { @@ -640,8 +637,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)  	if (xprt) {  		rqstp->rq_xprt = xprt;  		svc_xprt_get(xprt); -		rqstp->rq_reserved = serv->sv_max_mesg; -		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);  		/* As there is a shortage of threads and this request  		 * had to be queued, don't allow the thread to wait so @@ -738,6 +733,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)  		else  			len = xprt->xpt_ops->xpo_recvfrom(rqstp);  		dprintk("svc: got len=%d\n", len); +		rqstp->rq_reserved = serv->sv_max_mesg; +		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);  	}  	svc_xprt_received(xprt); @@ -794,7 +791,8 @@ int svc_send(struct svc_rqst *rqstp)  	/* Grab mutex to serialize outgoing data. */  	mutex_lock(&xprt->xpt_mutex); -	if (test_bit(XPT_DEAD, &xprt->xpt_flags)) +	if (test_bit(XPT_DEAD, &xprt->xpt_flags) +			|| test_bit(XPT_CLOSE, &xprt->xpt_flags))  		len = -ENOTCONN;  	else  		len = xprt->xpt_ops->xpo_sendto(rqstp); diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 18bc130255a..998aa8c1807 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1129,9 +1129,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)  	if (len >= 0)  		svsk->sk_tcplen += len;  	if (len != want) { +		svc_tcp_save_pages(svsk, rqstp);  		if (len < 0 && len != -EAGAIN)  			goto err_other; -		svc_tcp_save_pages(svsk, rqstp);  		dprintk("svc: incomplete TCP record (%d of %d)\n",  			svsk->sk_tcplen, svsk->sk_reclen);  		goto err_noclose; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index a5a402a7d21..5d7f61d7559 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -969,11 +969,11 @@ static bool xprt_dynamic_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)  	return false;  } -static void xprt_alloc_slot(struct rpc_task *task) +void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task)  { -	struct rpc_xprt	*xprt = task->tk_xprt;  	struct rpc_rqst *req; +	spin_lock(&xprt->reserve_lock);  	if (!list_empty(&xprt->free)) {  		req = list_entry(xprt->free.next, struct rpc_rqst, rq_list);  		list_del(&req->rq_list); @@ -994,12 +994,29 @@ static void xprt_alloc_slot(struct rpc_task *task)  	default:  		task->tk_status = -EAGAIN;  	} +	spin_unlock(&xprt->reserve_lock);  	return;  out_init_req:  	task->tk_status = 0;  	task->tk_rqstp = req;  	xprt_request_init(task, xprt); +	spin_unlock(&xprt->reserve_lock); +} +EXPORT_SYMBOL_GPL(xprt_alloc_slot); + +void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) +{ +	/* Note: grabbing the xprt_lock_write() ensures that we throttle +	 * new slot allocation if the transport is congested (i.e. when +	 * reconnecting a stream transport or when out of socket write +	 * buffer space). +	 */ +	if (xprt_lock_write(xprt, task)) { +		xprt_alloc_slot(xprt, task); +		xprt_release_write(xprt, task); +	}  } +EXPORT_SYMBOL_GPL(xprt_lock_and_alloc_slot);  static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)  { @@ -1083,20 +1100,9 @@ void xprt_reserve(struct rpc_task *task)  	if (task->tk_rqstp != NULL)  		return; -	/* Note: grabbing the xprt_lock_write() here is not strictly needed, -	 * but ensures that we throttle new slot allocation if the transport -	 * is congested (e.g. if reconnecting or if we're out of socket -	 * write buffer space). -	 */  	task->tk_timeout = 0;  	task->tk_status = -EAGAIN; -	if (!xprt_lock_write(xprt, task)) -		return; - -	spin_lock(&xprt->reserve_lock); -	xprt_alloc_slot(task); -	spin_unlock(&xprt->reserve_lock); -	xprt_release_write(xprt, task); +	xprt->ops->alloc_slot(xprt, task);  }  static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 06cdbff79e4..5d9202dc7cb 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -713,6 +713,7 @@ static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)  static struct rpc_xprt_ops xprt_rdma_procs = {  	.reserve_xprt		= xprt_rdma_reserve_xprt,  	.release_xprt		= xprt_release_xprt_cong, /* sunrpc/xprt.c */ +	.alloc_slot		= xprt_alloc_slot,  	.release_request	= xprt_release_rqst_cong,       /* ditto */  	.set_retrans_timeout	= xprt_set_retrans_timeout_def, /* ditto */  	.rpcbind		= rpcb_getport_async,	/* sunrpc/rpcb_clnt.c */ diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 400567243f8..a35b8e52e55 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -2473,6 +2473,7 @@ static void bc_destroy(struct rpc_xprt *xprt)  static struct rpc_xprt_ops xs_local_ops = {  	.reserve_xprt		= xprt_reserve_xprt,  	.release_xprt		= xs_tcp_release_xprt, +	.alloc_slot		= xprt_alloc_slot,  	.rpcbind		= xs_local_rpcbind,  	.set_port		= xs_local_set_port,  	.connect		= xs_connect, @@ -2489,6 +2490,7 @@ static struct rpc_xprt_ops xs_udp_ops = {  	.set_buffer_size	= xs_udp_set_buffer_size,  	.reserve_xprt		= xprt_reserve_xprt_cong,  	.release_xprt		= xprt_release_xprt_cong, +	.alloc_slot		= xprt_alloc_slot,  	.rpcbind		= rpcb_getport_async,  	.set_port		= xs_set_port,  	.connect		= xs_connect, @@ -2506,6 +2508,7 @@ static struct rpc_xprt_ops xs_udp_ops = {  static struct rpc_xprt_ops xs_tcp_ops = {  	.reserve_xprt		= xprt_reserve_xprt,  	.release_xprt		= xs_tcp_release_xprt, +	.alloc_slot		= xprt_lock_and_alloc_slot,  	.rpcbind		= rpcb_getport_async,  	.set_port		= xs_set_port,  	.connect		= xs_connect,  |