]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.4.83/sunrpc-fix-races-in-xs_nospace.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.4.83 / sunrpc-fix-races-in-xs_nospace.patch
CommitLineData
cb18dd13
GKH
1From 06ea0bfe6e6043cb56a78935a19f6f8ebc636226 Mon Sep 17 00:00:00 2001
2From: Trond Myklebust <trond.myklebust@primarydata.com>
3Date: Tue, 11 Feb 2014 09:15:54 -0500
4Subject: SUNRPC: Fix races in xs_nospace()
5
6From: Trond Myklebust <trond.myklebust@primarydata.com>
7
8commit 06ea0bfe6e6043cb56a78935a19f6f8ebc636226 upstream.
9
10When a send failure occurs due to the socket being out of buffer space,
11we call xs_nospace() in order to have the RPC task wait until the
12socket has drained enough to make it worth while trying again.
13The current patch fixes a race in which the socket is drained before
14we get round to setting up the machinery in xs_nospace(), and which
15is reported to cause hangs.
16
17Link: http://lkml.kernel.org/r/20140210170315.33dfc621@notabene.brown
18Fixes: a9a6b52ee1ba (SUNRPC: Don't start the retransmission timer...)
19Reported-by: Neil Brown <neilb@suse.com>
20Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
21Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22
23---
24 net/sunrpc/xprtsock.c | 6 +++++-
25 1 file changed, 5 insertions(+), 1 deletion(-)
26
27--- a/net/sunrpc/xprtsock.c
28+++ b/net/sunrpc/xprtsock.c
29@@ -501,6 +501,7 @@ static int xs_nospace(struct rpc_task *t
30 struct rpc_rqst *req = task->tk_rqstp;
31 struct rpc_xprt *xprt = req->rq_xprt;
32 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
33+ struct sock *sk = transport->inet;
34 int ret = -EAGAIN;
35
36 dprintk("RPC: %5u xmit incomplete (%u left of %u)\n",
37@@ -518,7 +519,7 @@ static int xs_nospace(struct rpc_task *t
38 * window size
39 */
40 set_bit(SOCK_NOSPACE, &transport->sock->flags);
41- transport->inet->sk_write_pending++;
42+ sk->sk_write_pending++;
43 /* ...and wait for more buffer space */
44 xprt_wait_for_buffer_space(task, xs_nospace_callback);
45 }
46@@ -528,6 +529,9 @@ static int xs_nospace(struct rpc_task *t
47 }
48
49 spin_unlock_bh(&xprt->transport_lock);
50+
51+ /* Race breaker in case memory is freed before above code is called */
52+ sk->sk_write_space(sk);
53 return ret;
54 }
55