|
@@ -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)
|