static void     xprt_init(struct rpc_xprt *xprt, struct net *net);
 static __be32  xprt_alloc_xid(struct rpc_xprt *xprt);
 static void     xprt_destroy(struct rpc_xprt *xprt);
+static void     xprt_request_init(struct rpc_task *task);
 
 static DEFINE_SPINLOCK(xprt_list_lock);
 static LIST_HEAD(xprt_list);
        rpc_sleep_on(&xprt->backlog, task, NULL);
 }
 
-static void xprt_wake_up_backlog(struct rpc_xprt *xprt)
+static bool __xprt_set_rq(struct rpc_task *task, void *data)
 {
-       if (rpc_wake_up_next(&xprt->backlog) == NULL)
+       struct rpc_rqst *req = data;
+
+       if (task->tk_rqstp == NULL) {
+               memset(req, 0, sizeof(*req));   /* mark unused */
+               task->tk_status = -EAGAIN;
+               task->tk_rqstp = req;
+               return true;
+       }
+       return false;
+}
+
+static bool xprt_wake_up_backlog(struct rpc_xprt *xprt, struct rpc_rqst *req)
+{
+       if (rpc_wake_up_first(&xprt->backlog, __xprt_set_rq, req) == NULL) {
                clear_bit(XPRT_CONGESTED, &xprt->state);
+               return false;
+       }
+       return true;
 }
 
 static bool xprt_throttle_congested(struct rpc_xprt *xprt, struct rpc_task *task)
 void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
 {
        spin_lock(&xprt->reserve_lock);
-       if (!xprt_dynamic_free_slot(xprt, req)) {
+       if (!xprt_wake_up_backlog(xprt, req) &&
+           !xprt_dynamic_free_slot(xprt, req)) {
                memset(req, 0, sizeof(*req));   /* mark unused */
                list_add(&req->rq_list, &xprt->free);
        }
-       xprt_wake_up_backlog(xprt);
        spin_unlock(&xprt->reserve_lock);
 }
 EXPORT_SYMBOL_GPL(xprt_free_slot);
        struct rpc_xprt *xprt = task->tk_xprt;
        struct rpc_rqst *req = task->tk_rqstp;
 
+       if (req->rq_task)
+               /* Already initialized */
+               return;
+
        req->rq_task    = task;
        req->rq_xprt    = xprt;
        req->rq_buffer  = NULL;
        struct rpc_xprt *xprt = task->tk_xprt;
 
        task->tk_status = 0;
-       if (task->tk_rqstp != NULL)
+       if (task->tk_rqstp != NULL) {
+               xprt_request_init(task);
                return;
+       }
 
        task->tk_status = -EAGAIN;
        xprt_do_reserve(xprt, task);
        }
 
        xprt = req->rq_xprt;
-       xprt_request_dequeue_xprt(task);
-       spin_lock(&xprt->transport_lock);
-       xprt->ops->release_xprt(xprt, task);
-       if (xprt->ops->release_request)
-               xprt->ops->release_request(task);
-       xprt_schedule_autodisconnect(xprt);
-       spin_unlock(&xprt->transport_lock);
-       if (req->rq_buffer)
-               xprt->ops->buf_free(task);
-       xdr_free_bvec(&req->rq_rcv_buf);
-       xdr_free_bvec(&req->rq_snd_buf);
-       if (req->rq_cred != NULL)
-               put_rpccred(req->rq_cred);
-       task->tk_rqstp = NULL;
-       if (req->rq_release_snd_buf)
-               req->rq_release_snd_buf(req);
+       if (xprt) {
+               xprt_request_dequeue_xprt(task);
+               spin_lock(&xprt->transport_lock);
+               xprt->ops->release_xprt(xprt, task);
+               if (xprt->ops->release_request)
+                       xprt->ops->release_request(task);
+               xprt_schedule_autodisconnect(xprt);
+               spin_unlock(&xprt->transport_lock);
+               if (req->rq_buffer)
+                       xprt->ops->buf_free(task);
+               xdr_free_bvec(&req->rq_rcv_buf);
+               xdr_free_bvec(&req->rq_snd_buf);
+               if (req->rq_cred != NULL)
+                       put_rpccred(req->rq_cred);
+               if (req->rq_release_snd_buf)
+                       req->rq_release_snd_buf(req);
+       } else
+               xprt = task->tk_xprt;
 
+       task->tk_rqstp = NULL;
        if (likely(!bc_prealloc(req)))
                xprt->ops->free_slot(xprt, req);
        else