mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
SUNRPC: never enqueue a ->rq_cong request on ->sending
commit 298073181112a6ab6c30fe7971b99de968daf81e upstream. If the sending queue has a task without ->rq_cong set at the front, and then a number of tasks with ->rq_cong set such that they use the entire congestion window, then the queue deadlocks. The first entry cannot be processed until later entries complete. This scenario has been seen with a client using UDP to access a server, and the network connection breaking for a period of time - it doesn't recover. It never really makes sense for an ->rq_cong request to be on the ->sending queue, but it can happen when a request is being retried, and finds the transport if locked (XPRT_LOCKED). In this case we simple call __xprt_put_cong() and the deadlock goes away. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Zefan Li <lizefan@huawei.com>
This commit is contained in:
parent
faf7b6b0d4
commit
31469735a1
1 changed files with 3 additions and 0 deletions
|
@ -66,6 +66,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net);
|
|||
static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
|
||||
static void xprt_connect_status(struct rpc_task *task);
|
||||
static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
|
||||
static void __xprt_put_cong(struct rpc_xprt *, struct rpc_rqst *);
|
||||
static void xprt_destroy(struct rpc_xprt *xprt);
|
||||
|
||||
static DEFINE_SPINLOCK(xprt_list_lock);
|
||||
|
@ -269,6 +270,8 @@ int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
|
|||
}
|
||||
xprt_clear_locked(xprt);
|
||||
out_sleep:
|
||||
if (req)
|
||||
__xprt_put_cong(xprt, req);
|
||||
dprintk("RPC: %5u failed to lock transport %p\n", task->tk_pid, xprt);
|
||||
task->tk_timeout = 0;
|
||||
task->tk_status = -EAGAIN;
|
||||
|
|
Loading…
Reference in a new issue