diff options
Diffstat (limited to 'net/sunrpc/xprt.c')
| -rw-r--r-- | net/sunrpc/xprt.c | 34 | 
1 files changed, 20 insertions, 14 deletions
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)  |